Reputation: 57
Im attempting to make a standard menu UI in java and I'm having an issue.
So essentially Code 1
sets up the Jframe and calls code 2
.
The problem I'm having is that when the menu button is pressed I want it to load code 3
and then stay there until the exit button is pressed. But what is happening at the moment is that the mouse pressed is detected, it runs through the entirety of code 3
and returns to code 2
without repainting the menu bar or exit button that code 3
contains.
So what I'm looking to happen is that when code 3
is called I want it to stay there and display the content (that being the menu) until a mouse click is detected in the area on the exit_but
.
Any help would be great.
My code is show below;
Code 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);
}
}
Code 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);
}
}
Code 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");
}
}
Upvotes: 0
Views: 2446
Reputation: 347184
The main issue is you never actually add you new panel to anything which could display it (let alone update the UI to display it)
There are a number of ways you might be able to achieve this (more simply), CardLayout
is one. Another might be to make your own controller which can "push" and "pop" views as needed. This decouples the navigation as the current view does not need to know what the last view "should" be
For example...
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();
}
}
}
}
There's nothing stopping you from coupling this with a CardLayout
and using "names" instead of JComponent
when pushing elements on the Stack
instead
Upvotes: 3