Я создаю программу, которая требует замены текущего, видимого JPanel с другим. К сожалению, кажется, что это много, и все мои попытки закончились неудачей. Я могу успешно получить первый JPanel, чтобы появиться в моем JFrame, но замена JPanels приводит к пробелу JFrame.
Мой главный JFrame:
public class ShellFrame {
static CardLayout cl = new CardLayout(); //handles panel switching
static JFrame frame; //init swing on EDT
static MainMenu mm;
static Panel2 p2;
static Panel3 p3;
public static void main(String[] args) {
initFrame();
}
public static void initFrame() {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
frame = new JFrame();
frame.setDefaultCloseOperation(3);
frame.setLayout(cl);
mm = new MainMenu();
pp = new PlacementPanel();
//first panel added to frame will always show first
frame.add(mm, "MainMenu");
frame.pack(); //sizes frame to fit the panel being shown
frame.setVisible(true);
}
});
}
public static void switchPanel(String name) {
cl.show(frame.getContentPane(), name);
frame.pack();
}
public static void updatePanel2(/* args */) {
frame.removeAll();
p2 = new Panel2(/* args */);
frame.add(pp, "PlacementPanel");
frame.pack();
frame.validate();
frame.repaint();
}
Я пытаюсь использовать updatePanel2 для замены существующей панели с помощью новой Panel2, но она, похоже, не работает. Panel2 отлично работает на нем, но попытка использовать его в сочетании с моей программой просто дает пустое окно. Любая помощь будет принята с благодарностью!
that requires swapping out the current, visible JPanel with another
Посмотрите CardLayout на полный пример того, как это сделать правильно.
I've tried the card layout as well and got the same result
Хорошо прочитайте CardLayout
пособие CardLayout
(вам дали ссылку) и используйте пример учебного пособия из учебного пособия и настройте его под свои требования. То есть начните с рабочего кода, а затем настраивайте его, а не пытайтесь писать код с нуля, если вы не уверены в том, что делаете. Код, который вы разместили, НЕ является способом кодирования класса. Вы не должны использовать статические переменные и методы везде. CardLayout - правильное решение.
Вы должны сделать .setVisible(false);
на панель, которую вы хотите заменить.
Вот рабочий пример: он переключает панели при нажатии "ENTER"; Если вы скопируете это в среде IDE, автоматически получите импорт (shift + o в Eclipse);
public class MyFrame extends JFrame implements KeyListener {
private JButton button = new JButton("Change Panels");
private JPanel panelOnFrame = new JPanel();
private JPanel panel1 = new JPanel();
public MyFrame() {
// adding labels to panels, to distinguish them
panelOnFrame.add(new JLabel("panel on frame"));
panel1.add(new JLabel("panel 1"));
setSize(new Dimension(250,250));
setDefaultCloseOperation(EXIT_ON_CLOSE);
add(button);
add(panelOnFrame);
setVisible(true);
addKeyListener(this);
addKeyListener(this);
setFocusable(true);
}
public static void main(String[] args) {
MyFrame frame = new MyFrame();
}
@Override
public void keyPressed(KeyEvent k) {
if(k.getKeyCode() == KeyEvent.VK_ENTER){
//+-------------here является заменой:
panelOnFrame.setVisible(false);
this.add(panel1);
}
}
@Override
public void keyReleased(KeyEvent arg0) {
}
@Override
public void keyTyped(KeyEvent arg0) {
}
}
У меня есть приложение Swing, которое "свопирует" панели, когда пользователь нажимает клавишу "SPACE", показывая живой график работающего моделирования. Что я сделал:
public class MainPanel extends JPanel implements Runnable {
// Called when the JPanel is added to the JFrame
public void addNotify() {
super.addNotify();
animator = new ScheduledThreadPoolExecutor(1);
animator.scheduleAtFixedRate(this, 0, 1000L/60L, TimeUnit.MILLISECONDS);
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
if (spacePressed)
plot.render(g);
else
simulation.render(g);
}
public void run() {
simulation.update();
repaint();
}
}
public class PlotView {
public void render(Graphics g) {
//draw the plot here
}
}
public class SimulationView {
public void render(Graphics g) {
//draw simulation here
}
}
Это очень хорошо работает для моей задачи "показать живой сюжет". И там также подход CardLayout
, который вы можете превратить в новый отдельный вопрос, если у вас возникли проблемы. Удачи!
frame.setContentPane(thepanel)