我通過單擊按鈕將面板添加到框架中,每個面板都位于最后添加的面板下方,我通過 y 位置來實作setBounds這一點。還有第二個按鈕,它應該洗掉我添加的最新面板。它應該在每次點擊后繼續洗掉面板。我嘗試了一些解決方案,但都失敗了。
我的代碼:
public class lab3 {
static int y = 50;
static JButton addThread;
static JPanel results;
public static void main(String[] args) {
JFrame jFrame = new JFrame();
jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jFrame.setSize(550, 650);
jFrame.setTitle("Lab3");
jFrame.setVisible(true);
JPanel panelAddThread = new JPanel();
panelAddThread.setLayout(null);
panelAddThread.setBounds(0, 0, 550, 50);
panelAddThread.setBackground(Color.red);
JLabel threadLabel = new JLabel();
threadLabel.setText("Thread count: ");
addThread = new JButton();
addThread.setBounds(300, 0, 25, 25);
addThread.setText(" ");
addThread.setBorder(null);
addThread.addActionListener(e -> {
results = new JPanel();
results.setBounds(0, y, 550, 150);
results.setBackground(Color.blue);
results.setLayout(null);
jFrame.add(results);
jFrame.repaint();
y = y 150;
});
// Remove
JButton removeThread = new JButton();
removeThread.setBorder(null);
removeThread.setBounds(340, 0, 25, 25);
removeThread.setText("-");
removeThread.addActionListener(e -> {
});
panelAddThread.add(threadLabel);
panelAddThread.add(removeThread);
panelAddThread.add(addThread);
jFrame.add(panelAddThread); }
}
uj5u.com熱心網友回復:
我了解您要求提供( JButton )的ActionListener的代碼。removeThread
results實際上是JPanel您添加的最后一個,所以這是JPanel您需要洗掉的。但是,一旦洗掉它,您需要將其分配給新的 last JPanel,即添加的倒數第二個JPanel。
方法getComponents按添加順序回傳所有添加的組件。當您從 a 中洗掉一個組件Container并隨后呼叫 methodgetComponents時,回傳的陣列將不包含您剛剛洗掉的組件。因此,新的,最后一個JPanel是方法回傳的陣列中的最后一個元素getComponents。
剩下的就是處理“邊緣”情況。
這是該actionPerformed方法的代碼:
removeThread.addActionListener(e -> {
if (results != null) {
jFrame.remove(results);
jFrame.repaint();
y -= 150;
Container contentPane = jFrame.getContentPane();
Component[] cmpts = contentPane.getComponents();
int count = cmpts.length;
if (count > 1) {
results = (JPanel) cmpts[count - 1];
}
else {
results = null;
}
}
});
- 如果用戶在單擊
removeThread之前單擊addThread,則將results為空。 - 如果只有一個,添加
JPanel并洗掉它,那么我們需要設定results為 null。
為了完整起見,這里是整個程式,包括上述更改。
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class lab3 {
static int y = 50;
static JButton addThread;
static JPanel results;
public static void main(String[] args) {
JFrame jFrame = new JFrame();
jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jFrame.setSize(550, 650);
jFrame.setTitle("Lab3");
jFrame.setVisible(true);
JPanel panelAddThread = new JPanel();
panelAddThread.setLayout(null);
panelAddThread.setBounds(0, 0, 550, 50);
panelAddThread.setBackground(Color.red);
JLabel threadLabel = new JLabel();
threadLabel.setText("Thread count: ");
addThread = new JButton();
addThread.setBounds(300, 0, 25, 25);
addThread.setText(" ");
addThread.setBorder(null);
addThread.addActionListener(e -> {
results = new JPanel();
results.setBounds(0, y, 550, 150);
results.setBackground(Color.blue);
results.setLayout(null);
jFrame.add(results);
jFrame.repaint();
y = y 150;
});
// Remove
JButton removeThread = new JButton();
removeThread.setBorder(null);
removeThread.setBounds(340, 0, 25, 25);
removeThread.setText("-");
removeThread.addActionListener(e -> {
if (results != null) {
jFrame.remove(results);
jFrame.repaint();
y -= 150;
Container contentPane = jFrame.getContentPane();
Component[] cmpts = contentPane.getComponents();
int count = cmpts.length;
if (count > 1) {
results = (JPanel) cmpts[count - 1];
}
else {
results = null;
}
}
});
panelAddThread.add(threadLabel);
panelAddThread.add(removeThread);
panelAddThread.add(addThread);
jFrame.add(panelAddThread);
}
}
但是,我會以不同的方式撰寫您的程式,以便它使用Swing的布局管理器。考慮以下:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
public class LabThree implements Runnable {
private JFrame frame;
private JPanel container;
private JPanel results;
public void run() {
buildAndDisplayGui();
}
private void buildAndDisplayGui() {
frame = new JFrame("Lab 3");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(createButtonsPanel(), BorderLayout.PAGE_START);
frame.add(createMainPanel(), BorderLayout.CENTER);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
private JPanel createButtonsPanel() {
JPanel buttonsPanel = new JPanel(new FlowLayout(FlowLayout.TRAILING));
buttonsPanel.setBackground(Color.red);
JButton addThreadButton = new JButton("\u2795");
addThreadButton.addActionListener(this::addThread);
buttonsPanel.add(addThreadButton);
JButton removeThreadButton = new JButton("\u2796");
removeThreadButton.addActionListener(this::removeThread);
buttonsPanel.add(removeThreadButton);
return buttonsPanel;
}
private JScrollPane createMainPanel() {
container = new JPanel();
container.setLayout(new BoxLayout(container, BoxLayout.PAGE_AXIS));
JScrollPane scrollPane = new JScrollPane(container);
scrollPane.setPreferredSize(new Dimension(570, 620));
return scrollPane;
}
private void addThread(ActionEvent event) {
results = new JPanel();
results.setBackground(Color.blue);
Dimension dim = new Dimension(550, 150);
results.setMaximumSize(dim);
results.setMinimumSize(dim);
results.setPreferredSize(dim);
container.add(results);
container.revalidate();
}
private void removeThread(ActionEvent event) {
if (results != null) {
container.remove(results);
Component[] cmpts = container.getComponents();
int count = cmpts.length;
if (count > 0) {
results = (JPanel) cmpts[count - 1];
}
else {
results = null;
}
container.revalidate();
container.repaint();
}
}
public static void main(String[] args) {
EventQueue.invokeLater(new LabThree());
}
}
- 添加到JFrame的所有組件實際上都添加到其內容窗格中,默認情況下,
JPanel它的 [默認] 布局管理器是BorderLayout。 - 通常,只有在添加了所有組件之后,您才應該呼叫
setVisible(類的JFrame)方法。 - 在顯示 GUI 并從容器中添加或洗掉組件(例如
JPanel)后,您需要呼叫方法revalidate。有時您還需要在呼叫 methodrepaint之后呼叫 methodrevalidate。 - 如果單擊
addThreadButton多次,則并非所有添加JPanel的 s 都會可見,因此我使用JScrollPane。 - for 的文本
addThreadButton是 Unicode重加號,for 的文本removeThreadButton是重減號。 ActionListeners 是使用方法參考實作的。- 雖然不是必需的,但建議顯式啟動事件調度執行緒(EDT),這是在
main上述代碼中的方法中完成的。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/516701.html
標籤:爪哇摇摆框架面板
