Java Swing - 我的 JPanel 正在吃掉我的 JButton
Java Swing - My JPanel is eating my JButton
为了创建我的 GUI,我创建了 JPanel
的多个子类,每个子类都解决了一个特定的布局问题。
第一个是AltBoxLayout_JPanel
,灵感来自我之前提出的一个问题的答案(link:):它只是一对JPanel
s 相互依偎,内部的 BoxLayout
以首选方式分配组件,外部的 BorderLayout
将组件压缩到最小尺寸。
第二个是 Fieldset
,灵感来自同名的 HTML 标签:它同样由两个嵌套的 JPanel
组成,最外面的 TitleBorder
,在构造函数中给出的内部一个,其目的是在 Fieldset
区域内设置布局。
我分别测试了这两个专用组件,效果不错,对它们很满意。最近我需要同时使用它们:我想要一个 JButton
和一个 JTextArea
显示在另一个之上而不被人为扩展(即在 AltBoxLayout_JPanel
内),并被边框包围(即 Fieldset
中的 AltBoxLayout_JPanel
)。由于我所有的组件都已经过测试,所以我确信它会顺利进行。
没有。
不知何故,我的 JButton
不再可见了。我知道它在那里(我检查过)并且我 假设 它包含在 JTextArea
中,但我没有更多信息。下面是我的代码。
任何帮助拯救我的 JButton
的人都将不胜感激!
public class WhosebugQuestion extends JFrame {
private static final long serialVersionUID = -5644282466098799568L;
private JPanel contentPanel;
// Display area
private Fieldset fieldset;
private JButton button;
private JTextArea jTextArea;
/**
* Create the frame.
*/
public WhosebugQuestion() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 300, 140);
contentPanel = new JPanel();
contentPanel.setBorder(new EmptyBorder(5, 5, 5, 5));
contentPanel.setLayout(new BorderLayout(0, 0));
setContentPane(contentPanel);
// Testing new components
// JPanel fieldsetLayoutPanel = new JPanel();
// BoxLayout fieldsetLayout = new BoxLayout(fieldsetLayoutPanel, BoxLayout.PAGE_AXIS);
// fieldsetLayoutPanel.setLayout(fieldsetLayout);
JPanel fieldsetLayoutPanel_2 = new AltBoxLayout_JPanel(BoxLayout.PAGE_AXIS);
this.fieldset = new Fieldset("Fieldset title", fieldsetLayoutPanel_2, null);
this.button = new JButton("Button text");
this.jTextArea = new JTextArea("JTextArea here!");
this.jTextArea.setRows(5);
this.jTextArea.setColumns(20);
this.button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
System.out.println("Action executed: " + arg0.toString());
}});
fieldset.add(button);
fieldset.add(jTextArea);
contentPanel.add(fieldset);
System.out.println("Analysis of the components of the contentPanel:");
analyzeLayoutsOfComponentAndSubComponents(contentPanel, 0);
pack();
}
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
WhosebugQuestion frame = new WhosebugQuestion();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/** A method that studies the {@link JPanel} and its sub-{@link JPanel}s, iterating through all the component tree.
*
* @param c
* @param tab
*/
public static void analyzeLayoutsOfComponentAndSubComponents(JPanel c, int tab) {
System.out.println(repeatChar('\t', tab) + c.toString());
for(int i=0 ; i<c.getComponentCount() ; i++)
if( c.getComponent(i) instanceof JPanel )
analyzeLayoutsOfComponentAndSubComponents( (JPanel)c.getComponent(i), tab+1 );
}
public static String repeatChar(char c, int tab) {
StringBuffer support = new StringBuffer();
for(int i=0 ; i<tab ; i++) support.append(c);
return support.toString();
}
public class Fieldset extends JPanel {
private static final long serialVersionUID = -1464052286624448783L;
/** The {@link Border} of {@code this} {@link Fieldset}. */
private Border border;
/** The {@link JPanel} responsible for the layout management. */
public JPanel layoutPanel;
/** Creates a new {@link Fieldset}.
*
* @param colorBorder The {@link Color} of the border. If {@code null}, {@code Color.BLACK} is chosen.
*
*/
public Fieldset(String titleFieldset, JPanel panel, Color colorBorder) {
super();
this.border = new TitledBorder(new LineBorder(colorBorder == null ? Color.BLACK : colorBorder), titleFieldset);
this.setBorder(border);
this.layoutPanel = panel;
super.add(layoutPanel);
}
public Component add(Component component) {
this.layoutPanel.add(component);
return component;
}
}
public class AltBoxLayout_JPanel extends JPanel {
private static final long serialVersionUID = -8204033141468207723L;
private JPanel layoutPanel;
/** Creates a new {@link AltBoxLayout_JPanel}.
*
* @param axisOrientation A constant from the {@link BoxLayout} class representing the chosen insertion axis.
*/
public AltBoxLayout_JPanel(int axisOrientation) {
// ===== INNER PANEL =====
this.layoutPanel = new JPanel(); //This is the nested panel
layoutPanel.setLayout(new BoxLayout(layoutPanel, axisOrientation));
// ===== OUTER PANEL =====
this.setLayout(new BorderLayout());
this.add(layoutPanel, BorderLayout.PAGE_START);
System.out.println("Analysis of the components of the AltBoxLayout_JPanel:");
analyzeLayoutsOfComponentAndSubComponents(this, 0);
}
public void add(JComponent component) {
layoutPanel.add(component);
}
}
}
您的 Fieldset
class 中的 layoutPanel
似乎将组件堆叠在彼此之上,因为它的默认布局告诉它这样做。
只是开始,尝试在 Fieldset
:
的构造函数中为其设置一个简单的 BoxLayout
this.layoutPanel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
您的按钮将可见。所以,完整的构造函数应该是这样的:
public Fieldset(String titleFieldset, JPanel panel, Color colorBorder) {
super();
this.border = new TitledBorder(new LineBorder(colorBorder == null ? Color.BLACK : colorBorder), titleFieldset);
this.setBorder(border);
this.layoutPanel = panel;
this.layoutPanel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
super.add(layoutPanel);
}
为了创建我的 GUI,我创建了 JPanel
的多个子类,每个子类都解决了一个特定的布局问题。
第一个是AltBoxLayout_JPanel
,灵感来自我之前提出的一个问题的答案(link:JPanel
s 相互依偎,内部的 BoxLayout
以首选方式分配组件,外部的 BorderLayout
将组件压缩到最小尺寸。
第二个是 Fieldset
,灵感来自同名的 HTML 标签:它同样由两个嵌套的 JPanel
组成,最外面的 TitleBorder
,在构造函数中给出的内部一个,其目的是在 Fieldset
区域内设置布局。
我分别测试了这两个专用组件,效果不错,对它们很满意。最近我需要同时使用它们:我想要一个 JButton
和一个 JTextArea
显示在另一个之上而不被人为扩展(即在 AltBoxLayout_JPanel
内),并被边框包围(即 Fieldset
中的 AltBoxLayout_JPanel
)。由于我所有的组件都已经过测试,所以我确信它会顺利进行。
没有。
不知何故,我的 JButton
不再可见了。我知道它在那里(我检查过)并且我 假设 它包含在 JTextArea
中,但我没有更多信息。下面是我的代码。
任何帮助拯救我的 JButton
的人都将不胜感激!
public class WhosebugQuestion extends JFrame {
private static final long serialVersionUID = -5644282466098799568L;
private JPanel contentPanel;
// Display area
private Fieldset fieldset;
private JButton button;
private JTextArea jTextArea;
/**
* Create the frame.
*/
public WhosebugQuestion() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 300, 140);
contentPanel = new JPanel();
contentPanel.setBorder(new EmptyBorder(5, 5, 5, 5));
contentPanel.setLayout(new BorderLayout(0, 0));
setContentPane(contentPanel);
// Testing new components
// JPanel fieldsetLayoutPanel = new JPanel();
// BoxLayout fieldsetLayout = new BoxLayout(fieldsetLayoutPanel, BoxLayout.PAGE_AXIS);
// fieldsetLayoutPanel.setLayout(fieldsetLayout);
JPanel fieldsetLayoutPanel_2 = new AltBoxLayout_JPanel(BoxLayout.PAGE_AXIS);
this.fieldset = new Fieldset("Fieldset title", fieldsetLayoutPanel_2, null);
this.button = new JButton("Button text");
this.jTextArea = new JTextArea("JTextArea here!");
this.jTextArea.setRows(5);
this.jTextArea.setColumns(20);
this.button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
System.out.println("Action executed: " + arg0.toString());
}});
fieldset.add(button);
fieldset.add(jTextArea);
contentPanel.add(fieldset);
System.out.println("Analysis of the components of the contentPanel:");
analyzeLayoutsOfComponentAndSubComponents(contentPanel, 0);
pack();
}
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
WhosebugQuestion frame = new WhosebugQuestion();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/** A method that studies the {@link JPanel} and its sub-{@link JPanel}s, iterating through all the component tree.
*
* @param c
* @param tab
*/
public static void analyzeLayoutsOfComponentAndSubComponents(JPanel c, int tab) {
System.out.println(repeatChar('\t', tab) + c.toString());
for(int i=0 ; i<c.getComponentCount() ; i++)
if( c.getComponent(i) instanceof JPanel )
analyzeLayoutsOfComponentAndSubComponents( (JPanel)c.getComponent(i), tab+1 );
}
public static String repeatChar(char c, int tab) {
StringBuffer support = new StringBuffer();
for(int i=0 ; i<tab ; i++) support.append(c);
return support.toString();
}
public class Fieldset extends JPanel {
private static final long serialVersionUID = -1464052286624448783L;
/** The {@link Border} of {@code this} {@link Fieldset}. */
private Border border;
/** The {@link JPanel} responsible for the layout management. */
public JPanel layoutPanel;
/** Creates a new {@link Fieldset}.
*
* @param colorBorder The {@link Color} of the border. If {@code null}, {@code Color.BLACK} is chosen.
*
*/
public Fieldset(String titleFieldset, JPanel panel, Color colorBorder) {
super();
this.border = new TitledBorder(new LineBorder(colorBorder == null ? Color.BLACK : colorBorder), titleFieldset);
this.setBorder(border);
this.layoutPanel = panel;
super.add(layoutPanel);
}
public Component add(Component component) {
this.layoutPanel.add(component);
return component;
}
}
public class AltBoxLayout_JPanel extends JPanel {
private static final long serialVersionUID = -8204033141468207723L;
private JPanel layoutPanel;
/** Creates a new {@link AltBoxLayout_JPanel}.
*
* @param axisOrientation A constant from the {@link BoxLayout} class representing the chosen insertion axis.
*/
public AltBoxLayout_JPanel(int axisOrientation) {
// ===== INNER PANEL =====
this.layoutPanel = new JPanel(); //This is the nested panel
layoutPanel.setLayout(new BoxLayout(layoutPanel, axisOrientation));
// ===== OUTER PANEL =====
this.setLayout(new BorderLayout());
this.add(layoutPanel, BorderLayout.PAGE_START);
System.out.println("Analysis of the components of the AltBoxLayout_JPanel:");
analyzeLayoutsOfComponentAndSubComponents(this, 0);
}
public void add(JComponent component) {
layoutPanel.add(component);
}
}
}
您的 Fieldset
class 中的 layoutPanel
似乎将组件堆叠在彼此之上,因为它的默认布局告诉它这样做。
只是开始,尝试在 Fieldset
:
BoxLayout
this.layoutPanel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
您的按钮将可见。所以,完整的构造函数应该是这样的:
public Fieldset(String titleFieldset, JPanel panel, Color colorBorder) {
super();
this.border = new TitledBorder(new LineBorder(colorBorder == null ? Color.BLACK : colorBorder), titleFieldset);
this.setBorder(border);
this.layoutPanel = panel;
this.layoutPanel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
super.add(layoutPanel);
}