JPanel будет отображать кнопки правильно, но не будет отображать пользовательский JComponent правильно - PullRequest
1 голос
/ 06 февраля 2011

У меня есть класс Cell, который расширяет JComponent. Цель состоит в том, чтобы отображалась сетка ячеек, и каждая из них могла обрабатывать свои собственные события щелчка и т. Д. Это в основном плоская кнопка.

Когда я добавляю несколько ячеек к JPanel, отображается только одна из них. Если, используя тот же код, я заменяю свои ячейки кнопками, все работает как положено.

Что мне не хватает?

Основной метод

public static void main(String[] args){
    JFrame f = new JFrame();
    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    f.setSize(new Dimension(300,300));
    JPanel jp = new JPanel();
    jp.setLayout(new GridLayout(1, 3));
    if(true){//Use buttons instead of cells
        jp.add(new JButton("Button 1"));
        jp.add(new JButton("Button 2"));
        jp.add(new JButton("Button 3"));
    }
    else{ //Use cells instead of buttons
        Cell a = new Cell(10,0,0);
        Cell b = new Cell(10,0,1);
        Cell c = new Cell(10,0,2);
        jp.add(a,0);
        jp.add(b,1);
        jp.add(c,2);
    }

    f.add(jp);
    f.setVisible(true);
    }

Класс сотовой связи

public class Cell extends JComponent{
    private static int numCells=0;
    private Dimension size;
    private int dt;
    private int dl;
    private Color color;
    public Cell(int size, int dt, int dl){
        numCells++;
        Random rand = new Random();
        this.size = new Dimension(size,size);
        this.dt = dt;
        this.dl = dl;
        this.color = new Color(//Random color, but only in one :r, g, or b
            (numCells%3==0)?rand.nextInt(255):0,
            (numCells%3==1)?rand.nextInt(255):0,
            (numCells%3==2)?rand.nextInt(255):0
    );
        this.setPreferredSize(this.size);
        this.setMaximumSize(this.size);
        this.setMinimumSize(this.size);
        this.setBackground(color);
        this.setVisible(true);
        this.setOpaque(true);
    }
    public void amClicked(){
        JOptionPane.showMessageDialog(this.getParent(), 
                this.toString());
    }

    public String toString(){
        return ""+dt+","+dl;
    }
    public void paintComponent(Graphics g){
                Graphics ng = g.create();
    try{
        super.paintComponent(ng);
        ng.setColor(color); 
        System.out.println(String.format("%d,%d,%d,%d(%d,%d,%d)",
                this.getX(), this.getY(), this.getWidth(), this.getHeight(),
                this.color.getRed(),this.color.getGreen(),this.color.getBlue()));
        ng.fillRect(this.getX(), this.getY(), this.getWidth(), this.getHeight());
    }
    finally{
        ng.dispose();
    }
    }


}

Ответы [ 2 ]

1 голос
/ 06 февраля 2011

Вы добавляете 3 компонента, но только один окрашен в черный цвет. Добавьте границу красной линии к вашим ячейкам, чтобы увидеть:

  public Cell(int size, int dt, int dl) {
     numCells++;
     //.... code deleted

     // !!this.color = new Color(Color.BLACK); // *** won't compile!
     color = Color.black;

     //.... code deleted

     this.setOpaque(true);
     setBorder(BorderFactory.createLineBorder(Color.red, 2));  // **** add this
  }

Редактировать: эта линия выглядит схематично для меня:

     g.fillRect(this.getX(), this.getY(), this.getWidth(), this.getHeight());

Почему вы используете getX и getY здесь? Эти методы возвращают информацию о положении относительно контейнера, а не ячейки, но затем вы используете его для рисования в месте относительно ячейки, а не контейнера, поэтому черный прямоугольник будет отрисован от видимой ячейки, и это, вероятно, не то, что вы хотите. Возможно, вам нужно использовать 0 для обоих:

     g.fillRect(0, 0, this.getWidth(), this.getHeight());
1 голос
/ 06 февраля 2011

Одна очевидная ошибка в этом коде - это то, что вы применяете изменения к графическому объекту через setColor (), но не откатываете их назад.

Это четко указано в Javadocs :

Если вы переопределяете это в подклассе, вы не должны вносить постоянные изменения в передаваемые в Graphics.

Общее решение состоит в создании новогоГрафический объект, который вы получаете в качестве параметра через Graphics.create(), оборачивает ваш код в блок try-finally и удаляет новый графический объект через Graphics.dispose() в предложении finally.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...