java - 使用 Java 创建菜单 UI

标签 java user-interface jpanel

我正在尝试用 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/

相关文章:

Java JPanel 绘制缩放

java - 如何等待多线程 shell 脚本执行完成在我的 Web 服务中调用?

java - 是否可以在没有任何数据库功能的情况下在 Java GUI 应用程序运行时临时保存数据?

java - 如何找出项目的依赖关系? (它使用什么 jar /库等)

c# - WPF C# 应用程序从 SQL Server 获取数据的时间太长

ios - 如何在 iOS 中打开系统字体的高易读性替代品?

java - 在java中删除一个形状

java - 如何向 JTabbedPane 添加滚动条。基本上我有一个管理面板,它作为 TAB(JTabbedPane) 进一步附加在框架上

java - Eclipse 的最佳 UML 插件

java - 在循环和方法内使用 return