Swing 组件在 JButton 事件后重新格式化
Swing Components are reformatted after JButton event
这是我第一次post在这里,所以如果有格式错误请原谅我并告诉我如何去做。
我对 GridBagLayout 的编码有点陌生,所以我设法理解了它的基本概念。有时会出现格式完全消失的情况。
应该如何,一个漂亮的大 TextPane:
有时候怎么样,TP真小:
触发此问题的唯一方法是从 JButton 调用 window。
我粘贴了代码以在一堆位置调用 window (Error.showDialog(new Exception());
),它似乎在有 ActionListener 调用它时发生。
这是我打印错误消息的对话框。
public static void showDialog(Exception myException) {
ByteArrayOutputStream os = new ByteArrayOutputStream();
PrintStream ps = new PrintStream(os);
myException.printStackTrace(ps);
try {
ErrorString = os.toString("UTF8");
} catch (UnsupportedEncodingException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
JFrame window = new JFrame("Error");
window.setSize(550, 600);
window.setLocationRelativeTo(null);
window.setResizable(false);
window.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
JPanel panel = new JPanel(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
c.insets = new Insets(5, 5, 5, 5);
c.fill = GridBagConstraints.BOTH;
c.gridy = 0;
tpError = new JTextPane();
tpError.setPreferredSize(new Dimension(500, 500));
tpError.setEditable(false);
tpError.setText(ErrorString);
JScrollPane scrollPane = new JScrollPane(tpError, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
panel.add(scrollPane, c);
c.gridy++;
JPanel panelBtns = new JPanel(new FlowLayout());
JButton btnClose = new JButton("Schließen");
btnClose.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
window.setVisible(false);
window.dispose();
}
});
panelBtns.add(btnClose);
JButton btnSend = new JButton("Bericht");
btnSend.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent AE) {
try {
Desktop.getDesktop().browse(new URI("mailto:my.name@mail.de?subject=Fehler%20im%20Converter"));
} catch (IOException | URISyntaxException ex) {
ex.printStackTrace();
}
}
});
panelBtns.add(btnSend);
panel.add(panelBtns,c );
window.add(panel);
window.setVisible(true);
window.repaint();
}
如图所示,格式有时会重置。我之前多次遇到这个问题,但我只是忽略了它。这次重要的是它按照我的意愿去做。
tpError.setPreferredSize(new Dimension(500, 500));
不要对首选尺寸进行硬编码。
当您使用 GridBagLayout 时,当没有足够的 space 来以其首选大小显示组件时,组件将以其 "minimum size" 显示。相反,您需要使用 "fill" 约束等其他约束来控制组件 grows/shrinks 作为 space 可用更改的方式。
但是,更好的解决方案是不使用 GridBagLayout。相反,只需使用框架的默认布局,即 BorderLayout
。那么基本代码将是:
JTextPane textPane = new JTextPane();
JScrollPane scrollPane = new JScrollPane( textPane );
add(scrollPane, BorderLayout.CENTER);
add(panelButtons, BorderLayout.PAGE_END);
当您不必担心更复杂的约束时,就简单多了。
您忘记为文本窗格设置 weightx 和 weighty 属性。
JPanel panel = new JPanel(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
c.insets = new Insets(5, 5, 5, 5);
c.fill = GridBagConstraints.BOTH;
c.weightx = 1; // set weightx/y
c.weighty = 1;
c.gridy = 0;
JTextPane tpError = new JTextPane();
tpError.setEditable(false);
try {
tpError.setText(os.toString("UTF8"));
} catch (Exception e) {
e.printStackTrace();
}
JScrollPane scrollPane = new JScrollPane(tpError, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
panel.add(scrollPane, c);
c.gridy++;
c.weightx = 0; // clean weightx/y
c.weighty = 0;
JPanel panelBtns = new JPanel(new FlowLayout());
另一种可能性是将首选大小设置为滚动窗格(而不是 JTextPane)
JTextPane tpError = new JTextPane();
tpError.setEditable(false);
try {
tpError.setText(os.toString("UTF8"));
} catch (Exception e) {
e.printStackTrace();
}
JScrollPane scrollPane = new JScrollPane(tpError, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
scrollPane.setPreferredSize(new Dimension(500, 500));
panel.add(scrollPane, c);
这是我第一次post在这里,所以如果有格式错误请原谅我并告诉我如何去做。
我对 GridBagLayout 的编码有点陌生,所以我设法理解了它的基本概念。有时会出现格式完全消失的情况。
应该如何,一个漂亮的大 TextPane:
有时候怎么样,TP真小:
触发此问题的唯一方法是从 JButton 调用 window。
我粘贴了代码以在一堆位置调用 window (Error.showDialog(new Exception());
),它似乎在有 ActionListener 调用它时发生。
这是我打印错误消息的对话框。
public static void showDialog(Exception myException) {
ByteArrayOutputStream os = new ByteArrayOutputStream();
PrintStream ps = new PrintStream(os);
myException.printStackTrace(ps);
try {
ErrorString = os.toString("UTF8");
} catch (UnsupportedEncodingException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
JFrame window = new JFrame("Error");
window.setSize(550, 600);
window.setLocationRelativeTo(null);
window.setResizable(false);
window.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
JPanel panel = new JPanel(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
c.insets = new Insets(5, 5, 5, 5);
c.fill = GridBagConstraints.BOTH;
c.gridy = 0;
tpError = new JTextPane();
tpError.setPreferredSize(new Dimension(500, 500));
tpError.setEditable(false);
tpError.setText(ErrorString);
JScrollPane scrollPane = new JScrollPane(tpError, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
panel.add(scrollPane, c);
c.gridy++;
JPanel panelBtns = new JPanel(new FlowLayout());
JButton btnClose = new JButton("Schließen");
btnClose.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
window.setVisible(false);
window.dispose();
}
});
panelBtns.add(btnClose);
JButton btnSend = new JButton("Bericht");
btnSend.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent AE) {
try {
Desktop.getDesktop().browse(new URI("mailto:my.name@mail.de?subject=Fehler%20im%20Converter"));
} catch (IOException | URISyntaxException ex) {
ex.printStackTrace();
}
}
});
panelBtns.add(btnSend);
panel.add(panelBtns,c );
window.add(panel);
window.setVisible(true);
window.repaint();
}
如图所示,格式有时会重置。我之前多次遇到这个问题,但我只是忽略了它。这次重要的是它按照我的意愿去做。
tpError.setPreferredSize(new Dimension(500, 500));
不要对首选尺寸进行硬编码。
当您使用 GridBagLayout 时,当没有足够的 space 来以其首选大小显示组件时,组件将以其 "minimum size" 显示。相反,您需要使用 "fill" 约束等其他约束来控制组件 grows/shrinks 作为 space 可用更改的方式。
但是,更好的解决方案是不使用 GridBagLayout。相反,只需使用框架的默认布局,即 BorderLayout
。那么基本代码将是:
JTextPane textPane = new JTextPane();
JScrollPane scrollPane = new JScrollPane( textPane );
add(scrollPane, BorderLayout.CENTER);
add(panelButtons, BorderLayout.PAGE_END);
当您不必担心更复杂的约束时,就简单多了。
您忘记为文本窗格设置 weightx 和 weighty 属性。
JPanel panel = new JPanel(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
c.insets = new Insets(5, 5, 5, 5);
c.fill = GridBagConstraints.BOTH;
c.weightx = 1; // set weightx/y
c.weighty = 1;
c.gridy = 0;
JTextPane tpError = new JTextPane();
tpError.setEditable(false);
try {
tpError.setText(os.toString("UTF8"));
} catch (Exception e) {
e.printStackTrace();
}
JScrollPane scrollPane = new JScrollPane(tpError, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
panel.add(scrollPane, c);
c.gridy++;
c.weightx = 0; // clean weightx/y
c.weighty = 0;
JPanel panelBtns = new JPanel(new FlowLayout());
另一种可能性是将首选大小设置为滚动窗格(而不是 JTextPane)
JTextPane tpError = new JTextPane();
tpError.setEditable(false);
try {
tpError.setText(os.toString("UTF8"));
} catch (Exception e) {
e.printStackTrace();
}
JScrollPane scrollPane = new JScrollPane(tpError, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
scrollPane.setPreferredSize(new Dimension(500, 500));
panel.add(scrollPane, c);