gpt4 book ai didi

java - MigLayout 使用 JScrollPane 调整大小

转载 作者:搜寻专家 更新时间:2023-11-01 03:10:44 25 4
gpt4 key购买 nike

我搜索了一下,没有找到适合我的问题的答案。

我正在开发一个必须可调整大小的图形用户界面。它包含一个位于 JScrollPane 内的状态 JTextArea。这是我的问题。只要我不手动调整 JFrame 的大小,“初始”布局就会保留,一切看起来都很好。一旦我手动调整大小(如果 JTextArea 已经处于滚动模式),布局就会变得困惑。

这是一个 SSCCE(我去掉了大部分部分,同时保留了代码的结构。我希望这样更易读):

import java.awt.Color;
import java.awt.Font;

import javax.swing.BorderFactory;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSeparator;
import javax.swing.JSlider;
import javax.swing.JTabbedPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.border.TitledBorder;

import net.miginfocom.swing.MigLayout;

public class Tab extends JFrame {
private static final long serialVersionUID = 1L;
private JTextArea messageTextArea;
private JPanel optionPanel, messagePanel;
private JTabbedPane plotTabPane;

public static void main(String[] args) {
final Tab tab = new Tab();
tab.setSize(1000, 600);
tab.setVisible(true);
new Thread(new Runnable() {
@Override
public void run() {
int count = 0;
tab.printRawMessage("start");
while (true) {
try {
Thread.sleep(200);
} catch (InterruptedException e) {}
tab.printRawMessage("\ntestMessage" + count++);
}
}
}).start();
}

public Tab() {
super();
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
initComponents();
}

private void initComponents() {
JPanel mainPanel = new JPanel();
mainPanel.setLayout(new MigLayout("insets 0", "", ""));
mainPanel.add(getLeftTopPanel(), "shrinky, top, w 450!");
mainPanel.add(getRightPanel(), "spany 5, wrap, grow, pushx, wmin 400");
mainPanel.add(getMessagePanel(), "pushy, growy, w 450!");

JScrollPane contentScrollPane = new JScrollPane(mainPanel);
contentScrollPane.setBorder(BorderFactory.createEmptyBorder());
setContentPane(contentScrollPane);
}

protected JPanel getLeftTopPanel() {
if (optionPanel == null) {
optionPanel = new JPanel();
optionPanel.setBorder(BorderFactory.createTitledBorder(null, "Configuration", TitledBorder.LEFT, TitledBorder.TOP, new Font("null", Font.BOLD, 12), Color.BLUE));
optionPanel.setLayout(new MigLayout("insets 0", "", "top, align 50%"));

JLabel label = new JLabel("Choose");
label.setHorizontalAlignment(JLabel.RIGHT);
optionPanel.add(label, "w 65!");
optionPanel.add(new JSeparator(JSeparator.VERTICAL), "spany 5, growy, w 2!");
optionPanel.add(new JComboBox(new String[] {"option1", "option2", "option3"}), "span, growx, wrap");

optionPanel.add(new JLabel("Type"), "right");
optionPanel.add(new JTextField("3"), "w 65!, split 2");
optionPanel.add(new JLabel("Unit"), "wrap");

optionPanel.add(new JLabel("Slide"), "right");
optionPanel.add(new JSlider(0, 100), "span, growx, wrap");
}
return optionPanel;
}

protected JTabbedPane getRightPanel() {
if (plotTabPane == null) {
plotTabPane = new JTabbedPane();
plotTabPane.add("Tab1", new JPanel());
plotTabPane.add("Tab2", new JPanel());
}
return plotTabPane;
}

protected JPanel getMessagePanel() {
if (messagePanel == null) {
messagePanel = new JPanel();
messagePanel.setBorder(BorderFactory.createTitledBorder(null, "Status Console", TitledBorder.LEFT, TitledBorder.TOP, new Font("null", Font.BOLD, 12), Color.BLUE));
messagePanel.setLayout(new MigLayout("insets 0", "", "top, align 50%"));
messagePanel.add(new JScrollPane(getMessageTextArea()), "push, grow");
}
return messagePanel;
}

protected JTextArea getMessageTextArea() {
if (messageTextArea == null) {
messageTextArea = new JTextArea();
messageTextArea.setEditable(false);
messageTextArea.setFont(new Font(null, Font.PLAIN, 20));
messageTextArea.setBorder(BorderFactory.createEmptyBorder(4, 4, 4, 4));
}
return messageTextArea;
}

public void printRawMessage(String rawMessage) {
getMessageTextArea().append(rawMessage);
getMessageTextArea().setCaretPosition(getMessageTextArea().getText().length());
}
}

布局的事情基本上发生在 initComponents() 中。

查看问题:

  1. 启动应用程序(我使用 miglayout-4.0-swing.jar)。
  2. 稍等(不要调整窗口大小),直到有足够的消息在状态文本区域中创建滚动条。
  3. 这就是我想要的。 JTextArea 一直延伸到 JFrame 的底部,并在必要时滚动。
  4. 现在调整窗口大小。如您所见,一切都变得一团糟。只有当窗口最大化时才好。

这是两个屏幕截图。第一个是我想要的样子: Before resizing: good!第二个是调整大小后: After resizing: bad!

我的问题:有人可以告诉我,我如何在调整大小之前保持布局不变?我想让 JTextArea 一直到窗口底部。如果需要,滚动条应该出现。如果窗口太小(因为配置面板的高度是固定的),状态面板可以低于窗口底部的唯一方法。

我希望我说清楚了。如果没有,请询​​问。 ;)

编辑:如果您删除顶部的 JScrollPanel(包含所有组件的那个),您可以看到我想要的行为。只是改变

JScrollPane contentScrollPane = new JScrollPane(mainPanel);
contentScrollPane.setBorder(BorderFactory.createEmptyBorder());
setContentPane(contentScrollPane);

setContentPane(mainPanel);

明白我的意思。不幸的是,如果窗口非常小,我会通过这种方式松开滚动条。

最佳答案

关注您的状态区域并使用嵌套布局产生如下所示的结果。特别注意,

  • 使用 invokeLater() 在 EDT 上构建 GUI。
  • 使用 javax.swing.Timer 更新 EDT 上的 GUI。
  • 使用 pack() 使窗口适合其子组件的首选大小和布局。
  • 使用 DefaultCaret 的更新策略来控制滚动。
  • 避免在公共(public)访问器中进行不必要的惰性实例化。
  • 避免setXxxSize() ;明智地覆盖 getXxxSize()
  • 批判性地检查扩展 JFrame 的决定。

image

import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSeparator;
import javax.swing.JTabbedPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.Timer;
import javax.swing.border.TitledBorder;
import javax.swing.text.DefaultCaret;

public class Tab extends JFrame {

private JTextArea messageTextArea;
private JPanel optionPanel, messagePanel;
private JTabbedPane plotTabPane;

public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {

@Override
public void run() {

final Tab tab = new Tab();
tab.setVisible(true);
Timer t = new Timer(200, new ActionListener() {

int count = 0;

@Override
public void actionPerformed(ActionEvent e) {
tab.printRawMessage("testMessage" + count++);
}
});
t.start();
}
});
}

public Tab() {
initComponents();
}

private void initComponents() {
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel mainPanel = new JPanel(new GridLayout(1, 0));
Box leftPanel = new Box(BoxLayout.Y_AXIS);
leftPanel.add(getLeftTopPanel());
leftPanel.add(getMessagePanel());
mainPanel.add(leftPanel);
mainPanel.add(getRightPanel());
this.add(mainPanel);
this.pack();
this.setLocationRelativeTo(null);
}

protected JPanel getLeftTopPanel() {
optionPanel = new JPanel();
optionPanel.setBorder(BorderFactory.createTitledBorder(null,
"Configuration", TitledBorder.LEFT, TitledBorder.TOP,
new Font("null", Font.BOLD, 12), Color.BLUE));
JLabel label = new JLabel("Choose");
label.setHorizontalAlignment(JLabel.RIGHT);
optionPanel.add(label);
optionPanel.add(new JSeparator(JSeparator.VERTICAL));
optionPanel.add(new JComboBox(
new String[]{"option1", "option2", "option3"}));
optionPanel.add(new JLabel("Type"));
optionPanel.add(new JTextField("3"));
return optionPanel;
}

protected JTabbedPane getRightPanel() {
plotTabPane = new JTabbedPane();
plotTabPane.add("Tab1", new JPanel());
plotTabPane.add("Tab2", new JPanel());
return plotTabPane;
}

protected JPanel getMessagePanel() {
messagePanel = new JPanel(new GridLayout());
messagePanel.setBorder(BorderFactory.createTitledBorder(null,
"Status Console", TitledBorder.LEFT, TitledBorder.TOP,
new Font("null", Font.BOLD, 12), Color.BLUE));
final JScrollPane sp = new JScrollPane(getMessageTextArea());
sp.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
messagePanel.add(sp);
return messagePanel;
}

protected JTextArea getMessageTextArea() {
messageTextArea = new JTextArea("", 10, 19);
messageTextArea.setEditable(false);
messageTextArea.setFont(new Font(null, Font.PLAIN, 20));
messageTextArea.setBorder(BorderFactory.createEmptyBorder(4, 4, 4, 4));
DefaultCaret caret = (DefaultCaret) messageTextArea.getCaret();
caret.setUpdatePolicy(DefaultCaret.ALWAYS_UPDATE);
return messageTextArea;
}

public void printRawMessage(String rawMessage) {
messageTextArea.append(rawMessage + "\n");
}
}

关于java - MigLayout 使用 JScrollPane 调整大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11030191/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com