gpt4 book ai didi

java - 使用 JTextArea 时,MigLayout 在 JOption Pane 中导致异常。 FlowLayout 就好了

转载 作者:行者123 更新时间:2023-11-30 07:18:33 25 4
gpt4 key购买 nike

下面的示例程序显示了一个带有两个按钮的框架。按下使用 MigLayout 的第二个按钮会导致异常。使用 FlowLayout 的第一个按钮工作得很好。似乎是 MigLayout 中的错误?

import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;

import net.miginfocom.swing.MigLayout;

public class Main extends JPanel {

static private JFrame frame = new JFrame("Test MigLayout");

public Main() {
JButton flowLayoutButton = new JButton("FlowLayout");
JButton miglayoutButton = new JButton("MigLayout");
add(flowLayoutButton);
add(miglayoutButton);
flowLayoutButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent actionEventIn) {
showDialog(false);
}
});
miglayoutButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent actionEventIn) {
showDialog(true);
}
});
}

public static void main(String[] args) {
Main main = new Main();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setContentPane(main);
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
frame.pack();
frame.setVisible(true);
frame.setBounds(200, 200, 200, 200);
}
});
}
private void showDialog(boolean useMidgLayoutIn) {
JPanel panel = new JPanel(useMidgLayoutIn ? new MigLayout() : new FlowLayout());
JTextArea topTextArea = new JTextArea("Here is some junk text to fill up the Text Area.");
panel.add(topTextArea);
panel.add(new JButton("Button"));

JOptionPane optionPane = new JOptionPane(panel, JOptionPane.ERROR_MESSAGE);
JDialog dialog = optionPane.createDialog(frame, "Application Error");
dialog.setResizable(true);
dialog.pack();
dialog.setVisible(true);
}
}

最佳答案

NPE 的原因是一些与 JTextArea/JEditorPane 相关的 mig-internal magic(详情如下)。这可能会导致嵌套容器出现问题,一些父级有一个管理器来保持内部状态,f.i.在盒子布局中。

最简单的出路:不要嵌套 - MigLayout 旨在控制一个大面板。在添加到预制特殊容器(如 optionPane)的情况下,这不是一个选项:在这里它有助于将 textArea/editorPane 包装在 JScrollPane 中。

不完全确定这是否是一个错误,尽管仅在 getter (preferredLayouutSize) 中向上操纵容器层次结构看起来很可疑。

NPE 发生原因的详细信息:魔法的作用是强制父容器布局查询 prefSize:

public Dimension preferredLayoutSize(Container parent) {
synchronized (parent.getTreeLock()) {
if (lastParentSize == null
|| !parent.getSize().equals(lastParentSize)) {
for (ComponentWrapper wrapper : ccMap.keySet()) {
Component c = (Component) wrapper.getComponent();
if (c instanceof JTextArea
|| c instanceof JEditorPane
|| (c instanceof JComponent && Boolean.TRUE
.equals(((JComponent) c)
.getClientProperty("migLayout.dynamicAspectRatio")))) {
layoutContainer(parent);
break;
}
}
}

lastParentSize = parent.getSize();
return getSizeImpl(parent, LayoutUtil.PREF);
}
}

依次重新查询顶级容器的 prefSize(在 adjustWindowSize 中向下):

private void adjustWindowSize(ContainerWrapper parent) {
BoundSize wBounds = lc.getPackWidth();
BoundSize hBounds = lc.getPackHeight();

if (wBounds == null && hBounds == null)
return;

Window win = ((Window) SwingUtilities.getAncestorOfClass(Window.class,
(Component) parent.getComponent()));
if (win == null)
return;

Dimension prefSize = win.getPreferredSize();
....
}

当嵌套在 BoxLayout 中时,这会导致重新进入 checkTarget:

public Dimension preferredLayoutSize(Container target) {
Dimension size;
synchronized(this) {
checkContainer(target);
// checkRequests initializes all internal book-keeping
checkRequests();
// here's the NPE in the second round
size = new Dimension(xTotal.preferred, yTotal.preferred);
}
...
}

void checkRequests() {
// config only if not yet done earlier
if (xChildren == null || yChildren == null) {
// The requests have been invalidated... recalculate
// the request information.
int n = target.getComponentCount();
//JW: first time around the arrays of sz are initialized
xChildren = new SizeRequirements[n];
yChildren = new SizeRequirements[n];
for (int i = 0; i < n; i++) {
Component c = target.getComponent(i);
....
Dimension min = c.getMinimumSize();
Dimension typ = c.getPreferredSize();
....
}
....
// JW: never reached if c.getPref re-enters, that is xTotal remains null
if (absoluteAxis == X_AXIS) {
xTotal = SizeRequirements.getTiledSizeRequirements(xChildren);
yTotal = SizeRequirements.getAlignedSizeRequirements(yChildren);
} else {
xTotal = SizeRequirements.getAlignedSizeRequirements(xChildren);
yTotal = SizeRequirements.getTiledSizeRequirements(yChildren);
}

}
}

关于java - 使用 JTextArea 时,MigLayout 在 JOption Pane 中导致异常。 FlowLayout 就好了,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15302595/

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