添加的JPanel仅在通过其他方法添加时显示吗?

时间:2019-04-28 16:56:17

标签: java swing jpanel boxlayout

enter image description here我正在尝试创建一个程序,该程序首先添加JPanel行。添加JPanel后,可以通过单击“添加水平”并指定应添加正方形的行索引(从0开始)来添加正方形。

我正在尝试添加JPanel并添加其中一个正方形。 但是,此第一个正方形不会出现。当我添加另一个正方形时,就好像该正方形在那里,但是只是不可见。

您可以在所附的图像中看到对此的演示,其中索引2和索引3的第一个正方形完全不可见,而没有添加JLabel

如何修改代码,以便在单击“添加垂直” JButton之后立即显示第一个正方形?

import javax.swing.*;
import java.awt.*;
import javax.swing.event.*;
import java.awt.event.*;
public class HistoryEditor extends JFrame{


public static Color randomColor(){
    return new Color((float)Math.random(), (float)Math.random(), (float)Math.random());
}

public HistoryEditor(){

    setLayout(new BorderLayout());

    final JPanel mainPanel = new JPanel();
    mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.Y_AXIS));
    JPanel controlPanel = new JPanel(new FlowLayout());
    final JTextField tf = new JTextField(20);
    JButton addVertical = new JButton("Add Vertical");
    JButton addHorizontal = new JButton("Add Horizontal");
    JButton removeVertical = new JButton("Remove Vertical");

    addVertical.addActionListener(new ActionListener(){
        public void actionPerformed(ActionEvent e){
            JPanel newPanel = new JPanel();
            newPanel.setPreferredSize( new Dimension(getWidth(), 50) );
            newPanel.setMaximumSize( newPanel.getPreferredSize() );
            newPanel.setMinimumSize( newPanel.getPreferredSize() );
            newPanel.setBackground( HistoryEditor.randomColor() );
            newPanel.setLayout( new BoxLayout( newPanel, BoxLayout.X_AXIS ) );

            JPanel eventPanel = new JPanel();
            eventPanel.setBackground( HistoryEditor.randomColor() );
            eventPanel.setMaximumSize( new Dimension(50, newPanel.getHeight() ) );
            eventPanel.setMinimumSize( new Dimension(50, newPanel.getHeight() ) );
            eventPanel.setPreferredSize( new Dimension(50, newPanel.getHeight() ) );
            eventPanel.add( new JLabel( tf.getText() ) );
            eventPanel.revalidate();
            newPanel.add(eventPanel);
            newPanel.revalidate();
            mainPanel.add( newPanel );
            mainPanel.revalidate();
            mainPanel.repaint();
            eventPanel.repaint();   


        }
    });

    addHorizontal.addActionListener(new ActionListener(){
        public void actionPerformed(ActionEvent e){
            try{
                int index = Integer.parseInt(tf.getText());
                JPanel selectedPanel = (JPanel)mainPanel.getComponent( index );

                JPanel eventPanel = new JPanel();
                eventPanel.setBackground( HistoryEditor.randomColor() );
                eventPanel.setMaximumSize(new Dimension(50, selectedPanel.getHeight()));
                eventPanel.setMinimumSize(new Dimension(50, selectedPanel.getHeight()));
                eventPanel.add( new JLabel( tf.getText() ) );
                selectedPanel.add(eventPanel);
                selectedPanel.revalidate();
                selectedPanel.repaint();

            }catch(Exception ex){}
        }
    });


    removeVertical.addActionListener(new ActionListener(){
        public void actionPerformed(ActionEvent e){
            try{
                int index = Integer.parseInt(tf.getText());
                mainPanel.remove(index);
                mainPanel.revalidate();
                mainPanel.repaint();

            }catch(Exception ex){}
        }
    });


    controlPanel.add(tf);
    controlPanel.add(addVertical);
    controlPanel.add(addHorizontal);
    controlPanel.add(removeVertical);   
    add(mainPanel, BorderLayout.CENTER);
    add(controlPanel, BorderLayout.SOUTH);
    setSize(1000, 1000);
    setVisible(true);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

}

public static void main(String[]args){
    HistoryEditor he = new HistoryEditor();
}

}

1 个答案:

答案 0 :(得分:1)

eventPanel.setPreferredSize( new Dimension(50, newPanel.getHeight() ) );

在创建组件时,它们的大小为(0,0)。

因此,您将eventPanel的首选大小设置为(50,0),这意味着因为面板的高度为0,所以将看不到添加的组件。

您只需要在mainPanel上使用revalidate()repaint()。这将导致布局管理器被调用,并且mainPanel的所有子组件都将重新绘制。

此外,也不需要eventPanel。您可以将标签直接添加到newPanel中。您只需要确保使用:

label.setOpaque(true);

因此标签的背景将被绘制。

使用标签时,无需设置最大/最小尺寸,因为它们等于首选尺寸。