java可扩展JDialog
对于我的应用程序,我有一个java可扩展JDialog,java,swing,jdialog,Java,Swing,Jdialog,对于我的应用程序,我有一个JDialog,其中包含一个JPanel,带有一些基本的JTextFields和JButtons。这个想法是有一个按钮,可以展开JDialog,显示第二个JPanel,其中包含一些“高级”设置 我通过调用setPreferredSize()和pack()实现了这一点,但这并不十分优雅。一个“优雅”的解决方案是将第二个面板设置为null,因此当切换状态为“收回”时,pack()会忽略它 很抱歉,我不能向您提供代码(这大约是700个谎言),但它就像我说的,基本上是JDial
JDialog
,其中包含一个JPanel
,带有一些基本的JTextFields
和JButtons
。这个想法是有一个按钮,可以展开JDialog
,显示第二个JPanel
,其中包含一些“高级”设置
我通过调用setPreferredSize()
和pack()
实现了这一点,但这并不十分优雅。一个“优雅”的解决方案是将第二个面板设置为null,因此当切换状态为“收回”时,pack()会忽略它
很抱歉,我不能向您提供代码(这大约是700个谎言),但它就像我说的,基本上是JDialog中的两个jpanel
以下是一些图片:
问题:有没有一个技巧可以让这个扩展过程继续进行,而不必为扩展/正常状态设置固定的尺寸。可能有几种方法可以做到这一点,例如,您可以根据需要简单地添加和删除底部面板。如果可以,我希望避免这种情况,因为这会使管理布局更加困难 另一个解决方案是简单地使组件可见/不可见,但您需要找到一个布局管理器,它将实际处理不可见组件,就像它不存在一样(
0x0
)-是的,我在进行测试时遇到了一些问题
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class FlipDialog {
public static void main(String[] args) {
new FlipDialog();
}
public FlipDialog() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private JButton flip;
private JPanel bottom;
public TestPane() {
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.insets = new Insets(8, 8, 8, 8);
gbc.gridwidth = GridBagConstraints.REMAINDER;
JPanel top = new JPanel();
flip = new JButton("+");
top.add(flip);
add(top, gbc);
bottom = new JPanel();
bottom.add(new JLabel("Boo"));
bottom.setVisible(false);
add(bottom, gbc);
flip.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
bottom.setVisible(!bottom.isVisible());
if (bottom.isVisible()) {
flip.setText("-");
} else {
flip.setText("+");
}
revalidate();
Window window = SwingUtilities.windowForComponent(bottom);
window.pack();
}
});
}
}
}
需要注意的是,调用revalidate
可能与打包窗口无关
使用布局示例更新
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.AbstractSpinnerModel;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSpinner;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.EmptyBorder;
import javax.swing.border.TitledBorder;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
public class Test100 {
public static void main(String[] args) {
new Test100();
}
public Test100() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new SearchPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class SearchPane extends JPanel {
private ObjectsPane objectsPane;
private AdvanceSettingsPane advanceSettingsPane;
public SearchPane() {
setBorder(new EmptyBorder(8, 8, 8, 8));
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.weightx = 1;
gbc.weighty = 1;
gbc.fill = GridBagConstraints.BOTH;
objectsPane = new ObjectsPane();
add(objectsPane, gbc);
gbc.gridy++;
gbc.weighty = 0;
advanceSettingsPane = new AdvanceSettingsPane();
advanceSettingsPane.setVisible(false);
add(advanceSettingsPane, gbc);
objectsPane.addExpandCollapseListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
System.out.println(objectsPane.isExpanded());
advanceSettingsPane.setVisible(objectsPane.isExpanded());
Window window = SwingUtilities.windowForComponent(SearchPane.this);
window.pack();
}
});
}
public class ObjectsPane extends JPanel {
private JSpinner findField;
private JTextField replaceField;
private JButton expandButton;
private JButton replaceButton;
private JButton replaceAllButton;
private boolean expanded = false;
public ObjectsPane() {
setLayout(new GridBagLayout());
findField = new JSpinner(new AbstractSpinnerModel() {
@Override
public Object getValue() {
return "";
}
@Override
public void setValue(Object value) {
}
@Override
public Object getNextValue() {
return "";
}
@Override
public Object getPreviousValue() {
return "";
}
});
replaceField = new JTextField(10);
replaceButton = new JButton("Replace");
replaceAllButton = new JButton("Replace All");
expandButton = new JButton("+");
GridBagConstraints gbc = new GridBagConstraints();
gbc.insets = new Insets(4, 4, 4, 4);
gbc.gridx = 0;
gbc.gridy = 0;
gbc.gridwidth = GridBagConstraints.REMAINDER;
gbc.weightx = 1;
gbc.anchor = GridBagConstraints.WEST;
add(new JLabel("Objects found:"), gbc);
gbc.gridx = 0;
gbc.gridy = 1;
gbc.gridwidth = 1;
gbc.weightx = 0;
add(new JLabel("Find:"), gbc);
gbc.gridy = 2;
add(new JLabel("Replace:"), gbc);
gbc.gridx = 1;
gbc.gridy = 1;
gbc.weightx = 1;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridwidth = GridBagConstraints.REMAINDER;
add(findField, gbc);
gbc.gridy = 2;
add(replaceField, gbc);
gbc.anchor = GridBagConstraints.WEST;
gbc.gridwidth = 1;
gbc.weightx = 0;
gbc.gridx = 0;
gbc.gridy = 3;
gbc.fill = GridBagConstraints.NONE;
add(expandButton, gbc);
JPanel pnlButtons = new JPanel(new GridLayout(1, 2));
pnlButtons.add(replaceButton);
pnlButtons.add(replaceAllButton);
gbc.gridx = 1;
gbc.gridy = 3;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.weightx = 1;
gbc.gridwidth = GridBagConstraints.REMAINDER;
add(pnlButtons, gbc);
expandButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
expanded = !expanded;
if (expanded) {
expandButton.setText("-");
} else {
expandButton.setText("+");
}
fireStateChanged();
}
});
}
public boolean isExpanded() {
return expanded;
}
public void addExpandCollapseListener(ChangeListener listener) {
listenerList.add(ChangeListener.class, listener);
}
public void removeExpandCollapseListener(ChangeListener listener) {
listenerList.remove(ChangeListener.class, listener);
}
protected void fireStateChanged() {
ChangeListener[] listeners = listenerList.getListeners(ChangeListener.class);
if (listeners.length > 0) {
ChangeEvent evt = new ChangeEvent(this);
for (ChangeListener listener : listeners) {
listener.stateChanged(evt);
}
}
}
}
public class AdvanceSettingsPane extends JPanel {
public AdvanceSettingsPane() {
setBorder(new TitledBorder("Advance Settings"));
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
// gbc.gridy = 0;
gbc.weightx = 1;
gbc.anchor = GridBagConstraints.WEST;
gbc.gridwidth = GridBagConstraints.REMAINDER;
add(new JCheckBox("Live Update"), gbc);
add(new JCheckBox("Word search"), gbc);
add(new JCheckBox("Ignore Case"), gbc);
}
}
}
}
您可以使用
CardLayout
(用于扩展状态)并调用pack
,或者您可以添加/删除设置面板并调用pack
…程序员!很高兴再次见到你xD你能给我一些关于布局的基本信息吗。我读了关于oracle的教程,但我仍然不是100%了解我实际在做什么。出于某种原因,pack()会忽略这两个面板。这是什么原因造成的?以及哪种布局最适合这种情况(只有两个面板相互下方)。-是的,CardLayout
希望将容器大小调整为最大的子组件,而不管可见的是什么:P-我猜您必须手动执行“删除”是一个很好的调用!这太棒了!现在还有两个问题:1。除非我在两个面板上都设置了setPreferredSize,否则pack()将忽略它们。2.我在面板周围没有空白,所以感觉非常密集。添加一个空订单似乎没有帮助。是因为我使用了BorderLayout吗?组件的大小应由布局管理器确定,因此不需要调用setPreferredSize
。如果不知道布局管理器涉及到什么,很难诊断“集群”问题,但我要说的是,问题在于调用setPreferredSize
——请参阅更新的答案,没有setPreferredSize
调用,它工作得很好……这看起来很有希望。一旦我在代码中实现了这一点,我就会对其进行标记。非常感谢你!好啊这管用!非常感谢。pack()的问题是我的面板的布局为空。现在我把一切都搞定了。只是我的布局完全被破坏了。您认为哪种布局管理器最适合/最容易重新创建我的空布局?我怀疑一个布局管理器可以完成全部工作,但我会使用一系列容器,可能使用GridBagLayout
,但这只是我;)使用GridBagLayout,我的代码长度增加了一倍,看起来像垃圾:(我真的在考虑切换回null布局..我知道,我知道,好的编程习惯和东西..但它不应该让代码变得更简单更好..你可以切换回null布局,但你失去了api提供的所有好处(如打包和自动调整大小)。您可以编写自己的代码,但实际情况是,您只能复制已有的代码。您还将失去跨平台支持,因为布局考虑了不同平台使用的渲染技术的差异,这会改变组件的首选大小。。。