Java 单击JTOGLE按钮,在Jpanel内添加或删除JTextPane
我有一个JDialog,其中有一个名为“dialogPane”的主Jpanel 此JPanel“dialogPane”包含以下2个JPanelJava 单击JTOGLE按钮,在Jpanel内添加或删除JTextPane,java,swing,applet,japplet,swingbuilder,Java,Swing,Applet,Japplet,Swingbuilder,我有一个JDialog,其中有一个名为“dialogPane”的主Jpanel 此JPanel“dialogPane”包含以下2个JPanel 包含JTextArea的ContentPanel buttonBar,包含进度条和一个切换按钮 现在我的用例是 单击开关按钮开/关时,文本区域应隐藏(开)/显示(关) 单击切换按钮时,JTextArea应隐藏,对话框大小应减小(小) 再次单击切换按钮时,应显示JTextArea并调整对话框大小(大) 下面是切换按钮的actionListener。我的代码
private void ShowOrHideLogToggleButtonItemStateChanged(final ItemEvent e) {
final int state = e.getStateChange();
if (state == ItemEvent.SELECTED) {
ShowOrHideLogToggleButton.setText("Show Log");
dialogPane.remove(contentPanel);
dialogPane.updateUI();
dialogPane.revalidate();
dialogPane.repaint();
} else {
ShowOrHideLogToggleButton.setText("Hide Log");
dialogPane.add(contentPanel);
dialogPane.updateUI();
dialogPane.revalidate();
dialogPane.repaint();
this.pack();
}
}
注意:ContentPanel是包含JTextArea的Jpanel,dialogPane是包含ContentPanel的父Jpanel
最小、完整且可验证的示例(再现问题的代码)
你需要做的是重新包装你的窗户。以下是我的例子:
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Window;
import java.awt.event.ActionEvent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JToggleButton;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;
public class WindowRepack implements Runnable {
private static final String TEXT =
"Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod "
+ "tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. "
+ "At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd "
+ "gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem "
+ "ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod "
+ "tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. "
+ "At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd "
+ "gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.";
private final JTextArea area = new JTextArea(5, 40);
private final JScrollPane scroller = new JScrollPane(area);
private final JPanel mainPanel = new JPanel(new BorderLayout());
@Override
public void run() {
area.setText(TEXT);
area.setLineWrap(true);
area.setWrapStyleWord(true);
JToggleButton tb = new JToggleButton("Show text");
tb.addActionListener(this::updateUI);
JPanel buttonsPanel = new JPanel(new FlowLayout(FlowLayout.TRAILING));
buttonsPanel.add(tb);
// provide fix width for the buttons panel to avoid horizontal scaling of window.
Dimension defSize = buttonsPanel.getPreferredSize();
// temporary make the scroll bar visible to compute the correct width
scroller.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
buttonsPanel.setPreferredSize(new Dimension(scroller.getPreferredSize().width, defSize.height));
scroller.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
// done
mainPanel.add(buttonsPanel, BorderLayout.NORTH);
JFrame frm = new JFrame("Dynamic frame");
frm.add(mainPanel);
frm.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frm.pack();
frm.setLocationRelativeTo(null);
frm.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new WindowRepack());
}
private void updateUI(ActionEvent evt) {
JToggleButton btn = (JToggleButton) evt.getSource();
if (btn.isSelected()) {
btn.setText("Hide text");
mainPanel.add(scroller);
} else {
btn.setText("Show text");
mainPanel.remove(scroller);
}
Window w = SwingUtilities.windowForComponent(mainPanel);
w.pack();
}
}
我使用了JFrame
,但同样的方法也适用于JDialog
重要信息:只有在使用正确的布局管理器填充对话框时,此方法才有效。您需要做的是重新打包窗口。以下是我的例子:
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Window;
import java.awt.event.ActionEvent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JToggleButton;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;
public class WindowRepack implements Runnable {
private static final String TEXT =
"Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod "
+ "tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. "
+ "At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd "
+ "gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem "
+ "ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod "
+ "tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. "
+ "At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd "
+ "gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.";
private final JTextArea area = new JTextArea(5, 40);
private final JScrollPane scroller = new JScrollPane(area);
private final JPanel mainPanel = new JPanel(new BorderLayout());
@Override
public void run() {
area.setText(TEXT);
area.setLineWrap(true);
area.setWrapStyleWord(true);
JToggleButton tb = new JToggleButton("Show text");
tb.addActionListener(this::updateUI);
JPanel buttonsPanel = new JPanel(new FlowLayout(FlowLayout.TRAILING));
buttonsPanel.add(tb);
// provide fix width for the buttons panel to avoid horizontal scaling of window.
Dimension defSize = buttonsPanel.getPreferredSize();
// temporary make the scroll bar visible to compute the correct width
scroller.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
buttonsPanel.setPreferredSize(new Dimension(scroller.getPreferredSize().width, defSize.height));
scroller.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
// done
mainPanel.add(buttonsPanel, BorderLayout.NORTH);
JFrame frm = new JFrame("Dynamic frame");
frm.add(mainPanel);
frm.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frm.pack();
frm.setLocationRelativeTo(null);
frm.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new WindowRepack());
}
private void updateUI(ActionEvent evt) {
JToggleButton btn = (JToggleButton) evt.getSource();
if (btn.isSelected()) {
btn.setText("Hide text");
mainPanel.add(scroller);
} else {
btn.setText("Show text");
mainPanel.remove(scroller);
}
Window w = SwingUtilities.windowForComponent(mainPanel);
w.pack();
}
}
我使用了JFrame
,但同样的方法也适用于JDialog
重要信息:只有当您使用正确的布局管理器填充对话框时,这种方法才有效。首先,
updateUI
方法,大多数情况下不需要调用它<在适当的容器中使用code>repaint()和revalidate()
方法是更好的做法
其次,我不会采用添加/删除容器的方法(取决于容器JDialog使用的组件数量和布局管理器)。我会采取可见/不可见的方法
我已经做了一个SSCCE,以使其更清楚。这正是我个人喜欢的方式。如果你想看的话,请看一看。代码中有一些额外的注释
此外,正如@Sergiy Medvynsky所说的,在JFrame上工作的东西也在JDialog上工作
import java.awt.BorderLayout;
import java.awt.Dimension;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JToggleButton;
import javax.swing.SwingUtilities;
public class TestFrame extends JFrame {
private static final long serialVersionUID = 1965751967944243251L;
public TestFrame() {
super("A Frame");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
getContentPane().setLayout(new BorderLayout());
JToggleButton toggleButton = new JToggleButton("Show log");
JTextArea textArea = new JTextArea();
for (int i = 0; i < 144; i++) {
textArea.append("This is the text area log!\n");
}
JPanel panelWithTextArea = new JPanel(new BorderLayout());
JScrollPane sp = new JScrollPane(textArea);
sp.setPreferredSize(new Dimension(sp.getPreferredSize().width, 300)); //Max height for textarea
panelWithTextArea.add(sp);
panelWithTextArea.setVisible(false); //Initially invisible
//Add the item listener to toggleButton
toggleButton.addItemListener(e -> {
if (toggleButton.isSelected()) {
panelWithTextArea.setVisible(true); //Make it visible
toggleButton.setText("Hide Log");
} else {
panelWithTextArea.setVisible(false); //Back to invisible
toggleButton.setText("Show Log");
}
pack(); //Repack the frame after component is visible
});
getContentPane().add(toggleButton, BorderLayout.PAGE_START);
getContentPane().add(panelWithTextArea, BorderLayout.CENTER);
setLocationRelativeTo(null);
pack();
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
TestFrame f = new TestFrame();
f.setVisible(true);
});
}
}
导入java.awt.BorderLayout;
导入java.awt.Dimension;
导入javax.swing.JFrame;
导入javax.swing.JPanel;
导入javax.swing.JScrollPane;
导入javax.swing.JTextArea;
导入javax.swing.JToggleButton;
导入javax.swing.SwingUtilities;
公共类TestFrame扩展了JFrame{
私有静态最终长serialVersionUID=1965751967944243251L;
公共测试框架(){
超级(“框架”);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
getContentPane().setLayout(新的BorderLayout());
JToggleButton toggleButton=新的JToggleButton(“显示日志”);
JTextArea textArea=新的JTextArea();
对于(int i=0;i<144;i++){
textArea.append(“这是文本区域日志!\n”);
}
JPanel panelWithTextArea=新的JPanel(新的BorderLayout());
JScrollPane sp=新的JScrollPane(textArea);
sp.setPreferredSize(新维度(sp.getPreferredSize().width,300));//textarea的最大高度
panelWithTextArea.add(sp);
panelWithTextArea.setVisible(false);//最初不可见
//将项目侦听器添加到toggleButton
toggleButton.addItemListener(e->{
if(toggleButton.isSelected()){
panelWithTextArea.setVisible(true);//使其可见
toggleButton.setText(“隐藏日志”);
}否则{
panelWithTextArea.setVisible(false);//返回到不可见
toggleButton.setText(“显示日志”);
}
pack();//在组件可见后重新打包框架
});
getContentPane().add(切换按钮,BorderLayout.PAGE_START);
getContentPane().add(panelWithTextArea,BorderLayout.CENTER);
setLocationRelativeTo(空);
包装();
}
公共静态void main(字符串[]args){
SwingUtilities.invokeLater(()->{
TestFrame f=新的TestFrame();
f、 setVisible(真);
});
}
}
微型预览:
首先,
updateUI
方法,大多数情况下不需要调用它<在适当的容器中使用code>repaint()和revalidate()
方法是更好的做法
其次,我不会采用添加/删除容器的方法(取决于容器JDialog使用的组件数量和布局管理器)。我会采取可见/不可见的方法
我已经做了一个SSCCE,以使其更清楚。这正是我个人喜欢的方式。如果你想看的话,请看一看。代码中有一些额外的注释
此外,正如@Sergiy Medvynsky所说的,在JFrame上工作的东西也在JDialog上工作
import java.awt.BorderLayout;
import java.awt.Dimension;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JToggleButton;
import javax.swing.SwingUtilities;
public class TestFrame extends JFrame {
private static final long serialVersionUID = 1965751967944243251L;
public TestFrame() {
super("A Frame");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
getContentPane().setLayout(new BorderLayout());
JToggleButton toggleButton = new JToggleButton("Show log");
JTextArea textArea = new JTextArea();
for (int i = 0; i < 144; i++) {
textArea.append("This is the text area log!\n");
}
JPanel panelWithTextArea = new JPanel(new BorderLayout());
JScrollPane sp = new JScrollPane(textArea);
sp.setPreferredSize(new Dimension(sp.getPreferredSize().width, 300)); //Max height for textarea
panelWithTextArea.add(sp);
panelWithTextArea.setVisible(false); //Initially invisible
//Add the item listener to toggleButton
toggleButton.addItemListener(e -> {
if (toggleButton.isSelected()) {
panelWithTextArea.setVisible(true); //Make it visible
toggleButton.setText("Hide Log");
} else {
panelWithTextArea.setVisible(false); //Back to invisible
toggleButton.setText("Show Log");
}
pack(); //Repack the frame after component is visible
});
getContentPane().add(toggleButton, BorderLayout.PAGE_START);
getContentPane().add(panelWithTextArea, BorderLayout.CENTER);
setLocationRelativeTo(null);
pack();
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
TestFrame f = new TestFrame();
f.setVisible(true);
});
}
}
导入java.awt.BorderLayout;
导入java.awt.Dimension;
导入javax.swing.JFrame;
导入javax.swing.JPanel;
导入javax.swing.JScrollPane;
导入javax.swing.JTextArea;
导入javax.swing.JToggleButton;
导入javax.swing.SwingUtilities;
公共类TestFrame扩展了JFrame{
私有静态最终长serialVersionUID=1965751967944243251L;
公共测试框架(){
超级(“框架”);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
getContentPane().setLayout(新的BorderLayout());
JToggleButton toggleButton=新的JToggleButton(“显示日志”);
JTextArea textArea=新的JTextArea();
对于(int i=0;i<144;i++){
textArea.append(“这是文本区域日志!\n”);
}
JPanel panelWithTextArea=新的JPanel(新的BorderLayout());
JScrollPane sp=新的JScrollPane(textArea);
sp.setPreferredSize(新维度(sp.getPreferredSize().width,300));//textarea的最大高度
panelWithTextArea.add(sp);