2011-02-05 2 views
1

У меня есть класс Cell, который расширяет JComponent. Цель состоит в том, чтобы сетка ячеек отображалась, и каждый из них мог обрабатывать свои собственные события кликов и т. Д. Это в основном плоская кнопка.JPanel отобразит кнопки правильно, но не отобразит пользовательский 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(); 
    } 
    } 


} 

ответ

1

Вы добавляете 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 
    } 

Edit: Эта строка выглядит отрывочным мне:

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

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

 g.fillRect(0, 0, this.getWidth(), this.getHeight()); 
+0

Первоначально у меня были случайные цвета, но хотелось, чтобы цвет был либо только красным, только зеленым, либо только синим. В попытке избежать путаницы я удалил этот кусок кода перед отправкой. Я вернул его, так как часть «избежать путаницы» не работала – amccormack

+0

Я понимаю, почему ваш код не работает: это ваше использование getX() и getY(). См. Мой ответ выше. –

+0

Изменение этого.getX() и this.getY() до 0,0 делало трюк. – amccormack

1

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

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

Если переопределить в подклассе не следует вносить постоянные изменения в переданном в графике.

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