window 上的 JScrollPane shrink/collapse 最小化
JScrollPane shrink/collapse on window minimize
我有一个包含 JTextArea 的 JScrollPane。当 window 最小化然后恢复时,JScrollPane 将自行折叠。请注意,仅当 JTextArea 中的文本超过 JTextArea 的给定宽度 and/or 高度(即出现水平或垂直滚动条)时才会发生这种挤压。
这里的这个问题:JScrollpane loses size after minimize 提出了同样的问题,但这个问题从未得到解决,除了向 JScrollPane 添加 weightx、weighty 和 fill 约束,我已经开始了。
下面是一个演示问题的简化示例。 window 最小化并恢复后,如何让 JScrollPane 保持其大小?
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.ExecutionException;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
import javax.swing.border.EtchedBorder;
public class GUITest implements ActionListener {
JButton button = new JButton("Button");
JTextArea textArea = new JTextArea();
SwingWorker<String, String> mySwingWorker = null;
public static void main(String[] args) throws IOException {
GUITest tracer = new GUITest();
}
public GUITest() throws IOException {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
try {
createAndShowGUI();
} catch (IOException e) {
e.printStackTrace();
}
}
});
}
public void createAndShowGUI() throws IOException {
JFrame frame = new JFrame("GUI Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(false);
JPanel mainPanel = new JPanel();
mainPanel.setLayout(new GridBagLayout());
GridBagConstraints mainPanelConstraints = new GridBagConstraints();
mainPanelConstraints.gridx = 0;
mainPanelConstraints.gridy = 0;
mainPanelConstraints.fill = GridBagConstraints.BOTH;
button.addActionListener(this);
mainPanel.add(button, mainPanelConstraints);
mainPanelConstraints.gridx = 0;
mainPanelConstraints.gridy = 1;
mainPanelConstraints.fill = GridBagConstraints.BOTH;
mainPanel.add(buildTextAreaPanel(), mainPanelConstraints);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setVisible(true);
}
private JPanel buildTextAreaPanel() {
JPanel textAreaPanel = new JPanel();
textAreaPanel.setLayout(new GridBagLayout());
GridBagConstraints textAreaPanelConstraints = new GridBagConstraints();
textAreaPanel.setBorder(BorderFactory.createTitledBorder(new EtchedBorder(EtchedBorder.RAISED), "TextArea"));
textArea.setColumns(30);
textArea.setRows(15);
textArea.setEditable(false);
JScrollPane textAreaScrollPane = new JScrollPane(textArea);
textAreaScrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
textAreaScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
textAreaPanelConstraints.gridx = 0;
textAreaPanelConstraints.gridy = 0;
textAreaPanelConstraints.weightx = 1.0;
textAreaPanelConstraints.weighty = 1.0;
textAreaPanelConstraints.fill = GridBagConstraints.BOTH;
textAreaPanel.add(textAreaScrollPane, textAreaPanelConstraints);
return textAreaPanel;
}
public void actionPerformed(ActionEvent e) {
if (e.getSource() == button) {
mySwingWorker = new MySwingWorker();
mySwingWorker.execute();
}
}
private class MySwingWorker extends SwingWorker<String, String> {
public String doInBackground() throws Exception {
for (int i = 0; i < textArea.getRows(); i++) {
publish("text\n");
}
publish("more text\n");
return "Done.";
}
public void process(List<String> chunks) {
for (String msg : chunks) {
textArea.append(msg);
}
}
public void done() {
try {
String msg = get();
textArea.append("\n" + msg);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}
}
将父 Container(内容窗格)的布局设置为 FlowLayout
...
frame.getContentPane().setLayout(new FlowLayout());
frame.getContentPane().add(mainPanel);
...
我通过删除所有 GridBagLayouts 并将它们替换为 BorderLayouts 解决了这个特定代码示例中的收缩问题。我不知道为什么 JScrollPane 会像您在使用 GridBagLayout 时发现的那样做出反应。
从 class 构造函数中启动 Event Dispatch 线程让我感到非常不舒服。我将 SwingUtilities invokeLater 移到了主要方法中。
无论如何,这是代码。
package com.ggl.testing;
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.ExecutionException;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
import javax.swing.border.EtchedBorder;
public class JScrollPaneTest implements ActionListener {
JButton button = new JButton("Button");
JTextArea textArea = new JTextArea();
SwingWorker<String, String> mySwingWorker = null;
public static void main(String[] args) throws IOException {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
try {
new JScrollPaneTest().createAndShowGUI();
} catch (IOException e) {
e.printStackTrace();
}
}
});
}
public JScrollPaneTest() throws IOException {
}
public void createAndShowGUI() throws IOException {
JFrame frame = new JFrame("JScrollPane Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(true);
JPanel mainPanel = new JPanel();
mainPanel.setLayout(new BorderLayout());
mainPanel.add(button, BorderLayout.NORTH);
mainPanel.add(buildTextAreaPanel(), BorderLayout.CENTER);
button.addActionListener(this);
frame.add(mainPanel, BorderLayout.CENTER);
frame.pack();
frame.setVisible(true);
}
private JPanel buildTextAreaPanel() {
JPanel textAreaPanel = new JPanel();
textAreaPanel.setLayout(new BorderLayout());
textAreaPanel.setBorder(BorderFactory.createTitledBorder(
new EtchedBorder(EtchedBorder.RAISED), "TextArea"));
textArea.setColumns(30);
textArea.setRows(15);
textArea.setEditable(false);
JScrollPane textAreaScrollPane = new JScrollPane(textArea);
textAreaPanel.add(textAreaScrollPane, BorderLayout.CENTER);
return textAreaPanel;
}
public void actionPerformed(ActionEvent e) {
if (e.getSource() == button) {
mySwingWorker = new MySwingWorker();
mySwingWorker.execute();
}
}
private class MySwingWorker extends SwingWorker<String, String> {
public String doInBackground() throws Exception {
for (int i = 0; i < textArea.getRows(); i++) {
publish("text\n");
}
publish("more text\n");
return "Done.";
}
public void process(List<String> chunks) {
for (String msg : chunks) {
textArea.append(msg);
}
}
public void done() {
try {
String msg = get();
textArea.append("\n" + msg);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}
}
您需要在两种布局中设置weightx 和weighty。在 createAndShowGui 中,在添加文本区域面板之前将 mainPanelConstraints.weightx 和 mainPanelConstraints.weighty 设置为 1。
我有一个包含 JTextArea 的 JScrollPane。当 window 最小化然后恢复时,JScrollPane 将自行折叠。请注意,仅当 JTextArea 中的文本超过 JTextArea 的给定宽度 and/or 高度(即出现水平或垂直滚动条)时才会发生这种挤压。
这里的这个问题:JScrollpane loses size after minimize 提出了同样的问题,但这个问题从未得到解决,除了向 JScrollPane 添加 weightx、weighty 和 fill 约束,我已经开始了。
下面是一个演示问题的简化示例。 window 最小化并恢复后,如何让 JScrollPane 保持其大小?
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.ExecutionException;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
import javax.swing.border.EtchedBorder;
public class GUITest implements ActionListener {
JButton button = new JButton("Button");
JTextArea textArea = new JTextArea();
SwingWorker<String, String> mySwingWorker = null;
public static void main(String[] args) throws IOException {
GUITest tracer = new GUITest();
}
public GUITest() throws IOException {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
try {
createAndShowGUI();
} catch (IOException e) {
e.printStackTrace();
}
}
});
}
public void createAndShowGUI() throws IOException {
JFrame frame = new JFrame("GUI Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(false);
JPanel mainPanel = new JPanel();
mainPanel.setLayout(new GridBagLayout());
GridBagConstraints mainPanelConstraints = new GridBagConstraints();
mainPanelConstraints.gridx = 0;
mainPanelConstraints.gridy = 0;
mainPanelConstraints.fill = GridBagConstraints.BOTH;
button.addActionListener(this);
mainPanel.add(button, mainPanelConstraints);
mainPanelConstraints.gridx = 0;
mainPanelConstraints.gridy = 1;
mainPanelConstraints.fill = GridBagConstraints.BOTH;
mainPanel.add(buildTextAreaPanel(), mainPanelConstraints);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setVisible(true);
}
private JPanel buildTextAreaPanel() {
JPanel textAreaPanel = new JPanel();
textAreaPanel.setLayout(new GridBagLayout());
GridBagConstraints textAreaPanelConstraints = new GridBagConstraints();
textAreaPanel.setBorder(BorderFactory.createTitledBorder(new EtchedBorder(EtchedBorder.RAISED), "TextArea"));
textArea.setColumns(30);
textArea.setRows(15);
textArea.setEditable(false);
JScrollPane textAreaScrollPane = new JScrollPane(textArea);
textAreaScrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
textAreaScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
textAreaPanelConstraints.gridx = 0;
textAreaPanelConstraints.gridy = 0;
textAreaPanelConstraints.weightx = 1.0;
textAreaPanelConstraints.weighty = 1.0;
textAreaPanelConstraints.fill = GridBagConstraints.BOTH;
textAreaPanel.add(textAreaScrollPane, textAreaPanelConstraints);
return textAreaPanel;
}
public void actionPerformed(ActionEvent e) {
if (e.getSource() == button) {
mySwingWorker = new MySwingWorker();
mySwingWorker.execute();
}
}
private class MySwingWorker extends SwingWorker<String, String> {
public String doInBackground() throws Exception {
for (int i = 0; i < textArea.getRows(); i++) {
publish("text\n");
}
publish("more text\n");
return "Done.";
}
public void process(List<String> chunks) {
for (String msg : chunks) {
textArea.append(msg);
}
}
public void done() {
try {
String msg = get();
textArea.append("\n" + msg);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}
}
将父 Container(内容窗格)的布局设置为 FlowLayout
...
frame.getContentPane().setLayout(new FlowLayout());
frame.getContentPane().add(mainPanel);
...
我通过删除所有 GridBagLayouts 并将它们替换为 BorderLayouts 解决了这个特定代码示例中的收缩问题。我不知道为什么 JScrollPane 会像您在使用 GridBagLayout 时发现的那样做出反应。
从 class 构造函数中启动 Event Dispatch 线程让我感到非常不舒服。我将 SwingUtilities invokeLater 移到了主要方法中。
无论如何,这是代码。
package com.ggl.testing;
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.ExecutionException;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
import javax.swing.border.EtchedBorder;
public class JScrollPaneTest implements ActionListener {
JButton button = new JButton("Button");
JTextArea textArea = new JTextArea();
SwingWorker<String, String> mySwingWorker = null;
public static void main(String[] args) throws IOException {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
try {
new JScrollPaneTest().createAndShowGUI();
} catch (IOException e) {
e.printStackTrace();
}
}
});
}
public JScrollPaneTest() throws IOException {
}
public void createAndShowGUI() throws IOException {
JFrame frame = new JFrame("JScrollPane Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(true);
JPanel mainPanel = new JPanel();
mainPanel.setLayout(new BorderLayout());
mainPanel.add(button, BorderLayout.NORTH);
mainPanel.add(buildTextAreaPanel(), BorderLayout.CENTER);
button.addActionListener(this);
frame.add(mainPanel, BorderLayout.CENTER);
frame.pack();
frame.setVisible(true);
}
private JPanel buildTextAreaPanel() {
JPanel textAreaPanel = new JPanel();
textAreaPanel.setLayout(new BorderLayout());
textAreaPanel.setBorder(BorderFactory.createTitledBorder(
new EtchedBorder(EtchedBorder.RAISED), "TextArea"));
textArea.setColumns(30);
textArea.setRows(15);
textArea.setEditable(false);
JScrollPane textAreaScrollPane = new JScrollPane(textArea);
textAreaPanel.add(textAreaScrollPane, BorderLayout.CENTER);
return textAreaPanel;
}
public void actionPerformed(ActionEvent e) {
if (e.getSource() == button) {
mySwingWorker = new MySwingWorker();
mySwingWorker.execute();
}
}
private class MySwingWorker extends SwingWorker<String, String> {
public String doInBackground() throws Exception {
for (int i = 0; i < textArea.getRows(); i++) {
publish("text\n");
}
publish("more text\n");
return "Done.";
}
public void process(List<String> chunks) {
for (String msg : chunks) {
textArea.append(msg);
}
}
public void done() {
try {
String msg = get();
textArea.append("\n" + msg);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}
}
您需要在两种布局中设置weightx 和weighty。在 createAndShowGui 中,在添加文本区域面板之前将 mainPanelConstraints.weightx 和 mainPanelConstraints.weighty 设置为 1。