Recently I'm writing a mail system client using Java (I chose swing to write the GUI and use IDEA to hardcode my GUI). In the Compose module, I want to show or hide the textfield for CC and Bcc when I click the corresponding buttons.
So I googled and browsed the following questions and doc on the web:
- How to make JPanel scrollable in Java?
- How to make JPanel scrollable?
- Scrolling a JPanel
- Doc: JScrollPane
Finally, I chose the JScrollPane to implement it.
My simplified sample code is as follows (the original code is tedious):
import java.awt.CardLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
public class Demo extends JFrame implements ActionListener {
private static final long serialVersionUID = 1L;
private JLabel lbl1;
private JTextField txf1;
private JLabel lbl2;
private JTextField txf2;
// container for lbl2 and txf2, which should be able to be shown or hidden
private JPanel pnlContainer2;
private JLabel lbl3;
private JTextField txf3;
// container for lbl3 and txf3
private JPanel pnlContainer3;
private JButton btnShow;
// the container I want to move when I click btnShow
private JPanel pnlBody;
// the panel to hold my "cards"
// In this example, I include it just to show what controls are on my interface.
private JPanel pnlContent;
private JPanel pnlContainer;
// here, I want to use JScrollPane to make my pnlContainer scrollable
// to adapt to my interface
private JScrollPane scrollPane;
public Demo() {
init();
}
private void init() {
pnlContainer = new JPanel(new CardLayout(), true);
pnlContainer.setBounds(0, 0, 200, 180);
pnlContent = new JPanel(null, true);
pnlContent.setBounds(0, 0, 200, 180 + 50);
scrollPane = new JScrollPane(pnlContent, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED,
ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
scrollPane.setBounds(0, 0, 200, 180);
pnlContainer.add(scrollPane);
pnlBody = new JPanel(null, true);
lbl1 = new JLabel("lbl1");
lbl1.setBounds(10, 20, 40, 30);
txf1 = new JTextField();
txf1.setBounds(60, 20, 120, 30);
pnlContent.add(lbl1);
pnlContent.add(txf1);
pnlContainer2 = new JPanel(null, true);
pnlContainer2.setBounds(0, 70, 180, 30);
lbl2 = new JLabel("lbl2");
lbl2.setBounds(10, 0, 40, 30);
txf2 = new JTextField();
txf2.setBounds(60, 0, 120, 30);
pnlContainer2.add(lbl2);
pnlContainer2.add(txf2);
pnlContainer2.setVisible(false);
pnlContent.add(pnlContainer2);
pnlBody = new JPanel(null, true);
pnlBody.setBounds(0, 70, 180, 90);
pnlContainer3 = new JPanel(null, true);
pnlContainer3.setBounds(0, 0, 180, 30);
pnlBody.add(pnlContainer3);
lbl3 = new JLabel("lbl3");
lbl3.setBounds(10, 0, 40, 30);
txf3 = new JTextField();
txf3.setBounds(60, 0, 120, 30);
pnlContainer3.add(lbl3);
pnlContainer3.add(txf3);
btnShow = new JButton("show");
btnShow.setBounds(60, 50, 80, 30);
btnShow.addActionListener(this);
pnlBody.add(btnShow);
pnlContent.add(pnlBody);
this.add(pnlContainer);
this.setLayout(null);
this.setTitle("Demo");
this.setSize(200, 200);
this.setLocationRelativeTo(null);
this.setVisible(true);
this.setResizable(false);
// ImageIcon icon = new ImageIcon("E:\\Javarepo\\Hmail\\src\\main\\resources\\assets\\hmail.png");
// this.setIconImage(icon.getImage());
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
Object src = e.getSource();
if (src instanceof JButton) {
JButton btn = (JButton) src;
boolean showSelected = false;
String altText;
if (btn == btnShow) {
showSelected = btnShow.getText() == "show";
altText = showSelected ? "hide" : "show";
btnShow.setText(altText);
}
relayout(showSelected);
}
}
private void relayout(boolean showSelected) {
int x = pnlBody.getX();
int y = pnlBody.getY();
if (showSelected) {
pnlContainer2.setVisible(true);
pnlBody.setBounds(x, y + 50, 180, 90);
} else {
pnlContainer2.setVisible(false);
pnlBody.setBounds(x, y - 50, 180, 90);
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> new Demo());
}
}
However, no matter which JPanel I apply JScrollPane to, I cannot make my interface adaptive to the hide and show of my JContainer2.
How can I modify it, or what control to use to replace JScrollPane? Any suggestions will be welcome.
And here is my platform information:
java -version
java version "1.8.0_212" Java(TM) SE Runtime Environment (build 1.8.0_212-b10)
Java HotSpot(TM) 64-Bit Server VM (build 25.212-b10, mixed mode)
OS: win10 1909
arch: amd64