Реализация кнопок назад/вперед в Swing
У меня есть быстрый вопрос.
Я получаю немного опыта работы с Swing, и самый простой способ сделать это - составить достаточно большой графический интерфейс.
Как часть графического интерфейса, я хочу иметь кнопки "вперед" и "назад". Подход, который я пытаюсь предпринять, - это реализовать методы, которые подтолкнут текущий JPanel к стеку и получить предыдущее значение (будь то в прямом или обратном направлении (отсюда 2 стека)). Я не могу заставить его работать. Возможно, я полностью ошибаюсь, или, может быть, стек не может использоваться так, как я его использую. В любом случае, это действительно меня беспокоит. Я предполагаю, что есть, вероятно, более простые способы, такие как макет карты, но я думаю, что этот подход должен работать и что так раздражает.
Возможно, стоит отметить, что я использую базовый класс JFrame и меняю центральный JPanel в зависимости от экрана. Панель навигации постоянна как часть "базового класса", однако
Код этого "базового класса":
public class Main_Frame extends JFrame{
static JPanel nav_bar_panel;
JButton home;
JButton back;
JButton forward;
JPanel currentPanel;
static Stack<JPanel> previousPanels;
static Stack<JPanel> forwardPanels;
public Main_Frame(){
super("DEMO");
setSize(800,600);
setLayout(new BorderLayout());
setVisible(true);
add(nav_bar(), BorderLayout.NORTH);
currentPanel = init_display();
add(currentPanel, BorderLayout.CENTER);
previousPanels = new Stack<JPanel>();
forwardPanels = new Stack<JPanel>();
}
private JPanel nav_bar(){
ButtonPressHandler handler = new ButtonPressHandler();
nav_bar_panel = new JPanel(new FlowLayout(FlowLayout.LEFT, 10, 10));
back = new JButton("Back");
back.addActionListener(handler);
home = new JButton("Home");
home.addActionListener(handler);
forward = new JButton("Forward");
forward.addActionListener(handler);
nav_bar_panel.add(back);
nav_bar_panel.add(home);
nav_bar_panel.add(forward);
return nav_bar_panel;
}
private JPanel init_display(){
Home_Panel home_panel = new Home_Panel();
return home_panel;
}
public void change_display(JPanel myPanel){
invalidate();
remove(currentPanel);
previousPanels.push(currentPanel);
currentPanel = myPanel;
add(currentPanel);
validate();
}
public void previous_display(){
if(!previousPanels.empty()){
invalidate();
remove(currentPanel);
forwardPanels.push(currentPanel);
currentPanel = previousPanels.pop();
add(currentPanel);
validate();
}
}
public void forward_display(){
if(!forwardPanels.empty()){
invalidate();
remove(currentPanel);
previousPanels.push(currentPanel);
currentPanel = forwardPanels.pop();
add(currentPanel);
validate();
}
}
private class ButtonPressHandler implements ActionListener
{
public void actionPerformed( ActionEvent event )
{
if(event.getSource() == back){
previous_display();
System.out.print("You selected back");
} else if(event.getSource() == forward){
forward_display();
System.out.print("You selected forward");
}
} // end method actionPerformed
} // end private inner class TextFieldHandler
}
Ответы
Ответ 1
Вот пример использования CardLayout
.
![enter image description here]()
import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.util.Random;
import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
/** @see http://stackoverflow.com/questions/5654926 */
public class CardPanel extends JPanel {
private static final Random random = new Random();
private static final JPanel cards = new JPanel(new CardLayout());
private final String name;
public CardPanel(String name) {
this.name = name;
this.setPreferredSize(new Dimension(320, 240));
this.setBackground(new Color(random.nextInt()));
this.add(new JLabel(name));
}
@Override
public String toString() {
return name;
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
create();
}
});
}
private static void create() {
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
for (int i = 1; i < 9; i++) {
CardPanel p = new CardPanel("Panel " + String.valueOf(i));
cards.add(p, p.toString());
}
JPanel control = new JPanel();
control.add(new JButton(new AbstractAction("\u22b2Prev") {
@Override
public void actionPerformed(ActionEvent e) {
CardLayout cl = (CardLayout) cards.getLayout();
cl.previous(cards);
}
}));
control.add(new JButton(new AbstractAction("Next\u22b3") {
@Override
public void actionPerformed(ActionEvent e) {
CardLayout cl = (CardLayout) cards.getLayout();
cl.next(cards);
}
}));
f.add(cards, BorderLayout.CENTER);
f.add(control, BorderLayout.SOUTH);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
}
Ответ 2
Идея сделать все, что я могу использовать повторно, является хорошей. У Pity Swing этой функции не было, хотя
Откажитесь от Действия с макетом карты, который может попытаться сделать макет карты немного проще в использовании для чего-то вроде этого.
Ответ 3
Обычно я делаю это так:
-
У меня есть класс StepManager (пишите его один раз, используйте его навсегда), который обрабатывает всю логику, связанную с этапами. Он получил такие методы, как next(), previous(), reset(), isFirst() и isLast().
-
У меня есть кнопки "Далее" и "Предыдущая" с соответствующими действиями (или как вы хотите использовать для прослушивания взаимодействия с пользователем).
-
Код, связанный с кнопкой "Далее", вызывает stepManager.next() для извлечения индекса для следующего шага. Затем (когда у меня есть следующий шаг) я просто вызываю (другой метод) showStep (int index), чтобы отобразить фактический пользовательский интерфейс шага, соответствующий текущему индексу шага.
Каждый шаг представляет собой отдельный JPanel (Step01, Step02, Step03...).
public void showStep(int index) {
ContentPanel.removeAll();
ContentPanel.setLayout(new BorderLayout());
switch (index) {
case 0:
ContentPanel.add(Step01, BorderLayout.CENTER);
break;
case 1:
ContentPanel.add(Step02, BorderLayout.CENTER);
break;
case 2:
ContentPanel.add(Step03, BorderLayout.CENTER);
break;
case 3:
ContentPanel.add(Step04, BorderLayout.CENTER);
}
ContentPanel.validate();
ContentPanel.repaint();
}