我正在尝试用 java 制作标准菜单 UI,但遇到了问题。
因此,本质上,代码 1
设置 Jframe 并调用代码 2
。
我遇到的问题是,当按下菜单按钮时,我希望它加载code 3
,然后停留在那里,直到按下退出按钮。但目前发生的情况是,检测到按下的鼠标,它会遍历整个代码3
并返回到代码2
,而无需重新绘制菜单栏或退出按钮code 3
包含的内容。
所以我希望发生的是,当调用 code 3
时,我希望它保留在那里并显示内容(即菜单)直到单击鼠标在 exit_but
区域检测到。
任何帮助都会很棒。
我的代码如下所示;
代码1:
import java.awt.*;
import java.awt.Graphics;
import javax.swing.*;
public class demo_project
{
public static void main(String[] args)
{
JFrame frame = new JFrame("Funhaus Project");
frame.setSize(720, 1280);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new demo_main_screen());
frame.pack();
frame.setVisible(true);
}
}
代码2:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class demo_main_screen extends JPanel
{
private ImageIcon menu_button;
private MouseListener listener = new MouseAdapter()
{
public void mouseClicked(MouseEvent e)
{
// Detects if the Video button was pressed
if (e.getPoint().x > 15 && e.getPoint().x < 183 && e.getPoint().y > 15 && e.getPoint().y < 85)
{
System.out.println("Menu Button Pressed");
new demo_menu();
}
}
};
// Paints the content to the screen
public void paint(Graphics g)
{
super.paintComponent(g);
menu_button.paintIcon(this, g, 15, 15);
}
// main screen constructor
public demo_main_screen()
{
addMouseListener(listener);
menu_button = new ImageIcon("res/menu_but.png");
setBackground(Color.white);
setPreferredSize(new Dimension(1280, 720));
setFocusable(true);
}
}
代码3:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class demo_menu extends JPanel
{
private ImageIcon menu, exit_but;
private MouseListener listener = new MouseAdapter()
{
public void mouseClicked(MouseEvent e)
{
if (e.getPoint().x > 230 && e.getPoint().x < 255 && e.getPoint().y > 15 && e.getPoint().y < 48)
{
return;
}
}
};
// main screen constructor
public demo_menu()
{
addMouseListener(listener);
menu = new ImageIcon("res/menu.png");
exit_but = new ImageIcon("res/exit_but.png");
setBackground(Color.white);
setPreferredSize(new Dimension(1280, 720));
setFocusable(true);
}
// Paints the content to the screen
public void paint(Graphics g)
{
super.paintComponent(g);
menu.paintIcon(this, g, 0, 0);
exit_but.paintIcon(this, g, 230, 15);
System.out.println("repaint");
}
}
最佳答案
主要问题是您从未真正将新面板添加到可以显示它的任何内容中(更不用说更新 UI 来显示它了)
有多种方法可以实现此目的(更简单),CardLayout
就是其中之一。另一种可能是制作自己的 Controller ,它可以根据需要“推送”和“弹出” View 。这使导航解耦,因为当前 View 不需要知道最后一个 View “应该”是什么
例如...
import java.awt.BorderLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.Stack;
import javax.imageio.ImageIO;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.table.DefaultTableModel;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
try {
BufferedImage background = ImageIO.read(new File("/Users/shane/Dropbox/MegaTokyo/issue142.jpg"));
DefaultTableModel model = new DefaultTableModel(new String[]{"A", "B", "C", "D", "E", "F"}, 10);
JFrame frame = new JFrame("Test");
JPanel contentPane = new JPanel(new BorderLayout());
frame.setContentPane(contentPane);
ViewController controller = new ViewController(contentPane);
controller.push(new MainMenu(controller));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
} catch (IOException ex) {
ex.printStackTrace();
}
}
});
}
public class MainMenu extends JPanel {
private ViewController controller;
public MainMenu(ViewController controller) {
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.insets = new Insets(100, 100, 100, 100);
JButton btn = new JButton("Sub Menu");
btn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
controller.push(new SubMenu(controller));
}
});
add(btn, gbc);
}
}
public class SubMenu extends JPanel {
private ViewController controller;
public SubMenu(ViewController controller) {
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
add(new JLabel("This is the sub menu"), gbc);
JButton btn = new JButton("Return");
btn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
controller.pop();
}
});
add(btn, gbc);
}
}
public class ViewController {
private Stack<JComponent> views;
private JComponent rootView;
public ViewController(JComponent rootView) {
this.rootView = rootView;
views = new Stack<>();
}
public void push(JComponent view) {
if (views.size() > 0) {
JComponent current = views.peek();
if (current != null) {
rootView.remove(current);
}
}
views.push(view);
rootView.add(view);
rootView.revalidate();
rootView.repaint();
}
public void pop() {
if (views.size() > 1) {
JComponent current = views.pop();
if (current != null) {
rootView.remove(current);
}
current = views.peek();
rootView.add(current);
rootView.revalidate();
rootView.repaint();
}
}
}
}
没有什么可以阻止您将其与 CardLayout
结合起来,并在将元素推送到 Stack
上时使用“名称”而不是 JComponent
关于java - 使用 Java 创建菜单 UI,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42475799/