I am trying to create a swing program. In my program I want to achieve something like this: right click on a panel and select the menu "Draw rectangle" and program should draw a very simple rectangle on the panel. Here is my code:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.BevelBorder;
public class MainWindow extends JFrame {
JFrame frame = null;
AboutDialog aboutDialog = null;
JLabel statusLabel = null; //label on statusPanel
public MainWindow() {
frame = new JFrame("Project");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//MENUS
JMenuBar menuBar = new JMenuBar(); //menubar
JMenu menuDosya = new JMenu("Dosya"); //menus on menubar
JMenu menuYardim = new JMenu("Yardım"); //menus in menus
menuBar.add(menuDosya);
menuBar.add(menuYardim);
JMenuItem menuItemCikis = new JMenuItem("Çıkış", KeyEvent.VK_Q); //dosya menus
menuItemCikis.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
System.exit(0);
}
});
menuDosya.add(menuItemCikis);
JMenuItem menuItemYardim = new JMenuItem("Hakkında", KeyEvent.VK_H); //hakkinda menus
menuItemYardim.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
JDialog f = new AboutDialog(new JFrame());
f.show();
}
});
menuYardim.add(menuItemYardim);
frame.setJMenuBar(menuBar);
//TOOLBAR
JToolBar toolbar = new JToolBar();
JButton exitButton = new JButton("Kapat");
toolbar.add(exitButton);
//STATUSBAR
JPanel statusPanel = new JPanel();
statusPanel.setBorder(new BevelBorder(BevelBorder.LOWERED));
frame.add(statusPanel, BorderLayout.SOUTH);
statusPanel.setPreferredSize(new Dimension(frame.getWidth(), 20));
statusPanel.setLayout(new BoxLayout(statusPanel, BoxLayout.X_AXIS));
statusLabel = new JLabel("Ready.");
statusLabel.setHorizontalAlignment(SwingConstants.LEFT);
statusPanel.add(statusLabel);
//MAIN CONTENT OF THE PROGRAM
final JPanel mainContentPanel = new JPanel();
//RIGHT CLICK MENU
final JPopupMenu menuSag = new JPopupMenu("RightClickMenu");
JMenuItem menuRightClickRectangle = new JMenuItem("draw rectangle");
menuRightClickRectangle.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
//CircleShape cs=new CircleShape();
mainContentPanel.add(new CircleShape()); //trying to draw.
mainContentPanel.repaint();
//mainContentPanel.repaint(); boyle olacak.
}
});
JMenuItem menuRightClickCircle = new JMenuItem("Daire çiz");
menuSag.add(menuRightClickRectangle);
menuSag.add(menuRightClickCircle);
mainContentPanel.addMouseListener(new MouseAdapter() {
public void mouseReleased(MouseEvent e) {
if (e.getButton() == MouseEvent.BUTTON3) {
menuSag.show(e.getComponent(), e.getX(), e.getY());
statusLabel.setText("X=" + e.getX() + " " + "Y=" + e.getY());
}
}
});
JButton west = new JButton("West");
JButton center = new JButton("Center");
JPanel content = new JPanel(); //framein icindeki genel panel. en genel panel bu.
content.setLayout(new BorderLayout());
content.add(toolbar, BorderLayout.NORTH);
content.add(statusPanel, BorderLayout.SOUTH);
content.add(west, BorderLayout.WEST);
content.add(mainContentPanel, BorderLayout.CENTER);
frame.setContentPane(content);
frame.setPreferredSize(new Dimension(400, 300));
frame.setLocationRelativeTo(null);
frame.pack();
frame.setVisible(true);
}
}
The problem is nothing is drawn on the panel. I guess there is an event loss in the program but i don't know how to solve this issue.
Please modify the code in the following way. Add a new class like this:
class MainPanel extends JPanel {
private List<Rectangle> rectangles = new ArrayList<Rectangle>();
private void addRectangle(Rectangle rectangle) {
rectangles.add(rectangle);
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
for (Rectangle rectangle : rectangles) {
g2.drawRect(rectangle.x, rectangle.y, rectangle.width, rectangle.height);
}
}
}
Then, instead of
final JPanel mainContentPanel = new JPanel();
you should do:
final MainPanel mainContentPanel = new MainPanel();
And the action listener for the menu item becomes something like this:
menuRightClickRectangle.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
// TODO: add your own logic here, currently a hardcoded rectangle
mainContentPanel.addRectangle(new Rectangle(10, 10, 100, 50));
mainContentPanel.repaint();
}
});
You can't do that by calling add method.To draw a shape you will have to override paintComponent method:
Example of drawing rectangle:
public void paintComponent(Graphics g){
g.setColor(Color.RED);
g.fillRect(50,50,50,50);
}
Hmm did a short example for you:
Test.java:
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.*;
public class Test {
private final JFrame frame = new JFrame();
private final MyPanel panel = new MyPanel();
private void createAndShowUI() {
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(false);
frame.add(panel);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new Test().createAndShowUI();
}
});
}
}
MyPanel.java:
class MyPanel extends JPanel {
private final JPopupMenu popupMenu = new JPopupMenu();
private final JMenuItem drawRectJMenu = new JMenuItem("Draw Rectangle here");
private int x = 0, y = 0;
private List<Rectangle> recs = new ArrayList<>();
public MyPanel() {
initComponents();
}
private void initComponents() {
setBounds(0, 0, 600, 600);
setPreferredSize(new Dimension(600, 600));
popupMenu.add(drawRectJMenu);
add(popupMenu);
addMouseListener(new MouseListener() {
#Override
public void mouseClicked(MouseEvent e) {
checkForTriggerEvent(e);
}
#Override
public void mouseEntered(MouseEvent e) {
}
#Override
public void mouseExited(MouseEvent e) {
}
#Override
public void mousePressed(MouseEvent e) {
}
#Override
public void mouseReleased(MouseEvent e) {
}
private void checkForTriggerEvent(MouseEvent e) {
if (e.getButton() == MouseEvent.BUTTON3) {
x = e.getX();
y = e.getY();
popupMenu.show(e.getComponent(), x,y);
}
}
});
drawRectJMenu.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
addRec(new Rectangle(x, y, 100, 100));
repaint();
}
});
}
public void addRec(Rectangle rec) {
recs.add(rec);
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
for (Rectangle rec : recs) {
g2d.drawRect(rec.x, rec.y, rec.width, rec.height);
}
}
}
Related
My JFrame uses a BorderLayout and it has a JLabel nested in several panels with different layout managers. I've tried several methods, however, cannot get the true position of where it sits in the frame.
I made a test UI and it seems like when other components are added the getX and getY parameters do not update. Other methods like getLocation do not provide a correct result either. Is there any way to obtain the exact location without manually calculating every possible offset from each component.
I am tracking the stated positions of the label (content) using a similar sized panel called content2 in the glass pane which I want to sit underneath content perfectly.
public class test {
private Dimension pSize = new Dimension(100,100);
private JFrame frame = new JFrame();
public static void main(String[] args) {
new test();
}
public test() {
//setup frame basics
frame.setPreferredSize(new Dimension(500,500));
frame.setLayout(new BorderLayout());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// setup GUI
JMenuBar j = new JMenuBar();
JMenuItem a = new JMenuItem("lol");
j.add(a);
JPanel j2 = new JPanel();
//setup main panel
JPanel main = new JPanel();
main.setBackground(Color.DARK_GRAY);
//setup side panel
FlowLayout f1 = new FlowLayout(FlowLayout.LEADING);
f1.setHgap(10);
f1.setVgap(0);
JPanel side = new JPanel();
side.setLayout(new BorderLayout());
side.setBackground(Color.gray);
side.setPreferredSize(new Dimension(150,100));
//setup JLabel (the main focus)
JLabel content = new JLabel("a");
content.setOpaque(true);
content.setBackground(Color.blue);
content.setPreferredSize(pSize);
// Setup the internal panels of side
JPanel top = new JPanel();//The panel where CONTENT is, the main focus
JPanel bot = new JPanel();
top.setBackground(Color.WHITE);
bot.setBackground(Color.orange);
top.setLayout(f1);
top.add(content);
side.add(top, BorderLayout.NORTH);
side.add(bot, BorderLayout.CENTER);
frame.add(main, BorderLayout.CENTER);
frame.add(side, BorderLayout.WEST);
frame.add(j2, BorderLayout.NORTH);
frame.setJMenuBar(j);
frame.pack();
frame.setVisible(true);
//Setting up the glass panel
JPanel pane = new JPanel();
pane.setLayout(null);
pane.setOpaque(false);
JPanel content2 = new JPanel();
content2.setBackground(Color.red);
content.revalidate();
int x = content.getX();
int y = content.getY();
// y = (int) content.getLocation().getY(); //returns a completely wrong location
//y = (int) content.getLocationOnScreen(); //returns a completely wrong location
/*
Point p = new Point();
p.setLocation(x, y);
p = SwingUtilities.convertPoint(content2, x, y, frame);
//SwingUtilities.convertPoint(content, p, frame);
y = (int) p.getY();
*
* Tried multiple SwingUtility converions to no avail
*
*/
// y = y +j.getHeight() + j2.getHeight(); // Manually calculating the Y off set works successfully but is too tedious for large project
y = y + content.getHeight();
content2.setBounds(x,y,100,100);
pane.add(content2);
frame.setGlassPane(pane);
frame.getGlassPane().setVisible(true);
frame.pack();
}
}
//frame.getContentPane().add(content);
//frame.add(content);
frame.setPreferredSize(new Dimension(500,500));
content.setBorder(BorderFactory.createEmptyBorder());
side.setLayout(new BorderLayout());
JPanel top = new JPanel();
JPanel bot = new JPanel();
top.setBackground(Color.WHITE);
bot.setBackground(Color.orange);
side.add(top, BorderLayout.NORTH);
top.setLayout(f1);
top.add(content);
side.add(bot, BorderLayout.CENTER);
frame.add(main, BorderLayout.CENTER);
frame.add(j2, BorderLayout.NORTH);
frame.add(side, BorderLayout.WEST);
frame.pack();
frame.setVisible(true);
JPanel pane = new JPanel();
pane.setLayout(null);
pane.setOpaque(false);
JPanel content2 = new JPanel();
content2.setBackground(Color.red);
content.revalidate();
int x = content.getX();
int y = content.getY();
// y = y +j.getHeight() + j2.getHeight();
y = y + content.getHeight();
content2.setBounds(x,y,100,100);
pane.add(content2);
frame.setGlassPane(pane);
frame.getGlassPane().setVisible(true);
frame.pack();
}
}
Conceptually you could make use of SwingUtilities.convertPoint or SwingUtilities.convertRectangle to convert between container contexts, for example...
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagLayout;
import java.awt.Rectangle;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.border.EmptyBorder;
public class Main {
public static void main(String[] args) {
new Main();
}
public Main() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
GlassPane glassPane = new GlassPane();
JFrame frame = new JFrame();
frame.setGlassPane(glassPane);
frame.add(new MainPane(glassPane));
glassPane.setVisible(true);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public interface Tracker {
public void addTrackable(Trackable trackable);
public void removeTrackable(Trackable trackable);
}
public interface Trackable {
public JComponent[] getTrackedComponents();
}
public class MainPane extends JPanel {
private JLabel label = new JLabel("Catch me if you can");
public MainPane(Tracker tracker) {
setLayout(new GridBagLayout());
setBorder(new EmptyBorder(32, 32, 32, 32));
add(label);
tracker.addTrackable(new Trackable() {
#Override
public JComponent[] getTrackedComponents() {
return new JComponent[] { label };
}
});
}
}
public class GlassPane extends JPanel implements Tracker {
private List<Trackable> trackables = new ArrayList<>(8);
public GlassPane() {
setOpaque(false);
}
#Override
public void addTrackable(Trackable trackable) {
trackables.add(trackable);
revalidate();
repaint();
}
#Override
public void removeTrackable(Trackable trackable) {
trackables.remove(trackable);
revalidate();
repaint();
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
g2d.setColor(Color.RED);
for (Trackable trackable : trackables) {
for (JComponent component : trackable.getTrackedComponents()) {
Rectangle relativeBounds = SwingUtilities.convertRectangle(component.getParent(), component.getBounds(), this);
g2d.draw(relativeBounds);
}
}
g2d.dispose();
}
}
}
Well, that's pretty boring, it's one component inside one container, let's trying something a little more complicated...
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Rectangle;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.border.CompoundBorder;
import javax.swing.border.EmptyBorder;
import javax.swing.border.LineBorder;
public class Main {
public static void main(String[] args) {
new Main();
}
public Main() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
GlassPane glassPane = new GlassPane();
JFrame frame = new JFrame();
frame.setLayout(new GridLayout(2, 2, 8, 8));
frame.add(new MainPane(glassPane));
frame.add(new MainPane(glassPane));
frame.add(new MainPane(glassPane));
frame.add(new MainPane(glassPane));
frame.setGlassPane(glassPane);
glassPane.setVisible(true);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public interface Tracker {
public void addTrackable(Trackable trackable);
public void removeTrackable(Trackable trackable);
}
public interface Trackable {
public JComponent[] getTrackedComponents();
}
public class MainPane extends JPanel {
private JLabel label = new JLabel("Catch me if you can");
public MainPane(Tracker tracker) {
setLayout(new GridBagLayout());
setBorder(new CompoundBorder(new LineBorder(Color.DARK_GRAY, 1, true), new EmptyBorder(32, 32, 32, 32)));
add(label);
tracker.addTrackable(new Trackable() {
#Override
public JComponent[] getTrackedComponents() {
return new JComponent[]{label};
}
});
}
}
public class GlassPane extends JPanel implements Tracker {
private List<Trackable> trackables = new ArrayList<>(8);
private List<Color> masterColors = new ArrayList<>(Arrays.asList(new Color[]{
Color.RED,
Color.GREEN,
Color.BLUE,
Color.CYAN,
Color.DARK_GRAY,
Color.GRAY,
Color.MAGENTA,
Color.ORANGE,
Color.PINK,
Color.YELLOW,}));
public GlassPane() {
setOpaque(false);
}
#Override
public void addTrackable(Trackable trackable) {
trackables.add(trackable);
revalidate();
repaint();
}
#Override
public void removeTrackable(Trackable trackable) {
trackables.remove(trackable);
revalidate();
repaint();
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
g2d.setColor(Color.RED);
List<Color> colors = new ArrayList<>(masterColors);
for (Trackable trackable : trackables) {
for (JComponent component : trackable.getTrackedComponents()) {
if (colors.isEmpty()) {
colors = new ArrayList<>(masterColors);
}
g2d.setColor(colors.remove(0));
Rectangle relativeBounds = SwingUtilities.convertRectangle(component.getParent(), component.getBounds(), this);
g2d.draw(relativeBounds);
}
}
g2d.dispose();
}
}
}
Here is a new smipler example program, trying to keep as close to your code as possible, that uses the convertRectangle but I can't manage to run it correctly
int y = (int) (r.getY() + r.getHeight()); ... are you deliberately trying to offset the "overlay"? This seems weird to me.
Another issue is, how does the GlassPane know when the child has changed position/size
So, I modified your code, getting rid of the "modification" to the x/y position (so I'm 100% sure that the conversion between context spaces is correct) and added a ComponentListener to monitor changes to the "target" component
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Rectangle;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import java.awt.*;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
public class Main {
private Dimension pSize = new Dimension(100, 100);
private JFrame frame = new JFrame();
private JLabel content = new JLabel("Grief");
private JPanel content2 = new JPanel();
private SidePane sidePane = new SidePane();
private GlassPane glass = new GlassPane();
private Menu menu = new Menu();
public static void main(String[] args) {
new Main();
}
public Main() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
content.setBackground(Color.green);
content.setPreferredSize(pSize);
content.setOpaque(true);
//setup frame basics
frame.setPreferredSize(new Dimension(500, 500));
frame.setLayout(new BorderLayout());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setGlassPane(glass);
frame.add(new MainPane());
// glass.setNewLocation();
// glass.revalidate();
frame.getGlassPane().setVisible(true);
// glass.setNewLocation();
frame.pack();
frame.setVisible(true);
}
});
}
public class MainPane extends JPanel {
public MainPane() {
//this.setBackground(Color.orange);
this.setLayout(new BorderLayout());
this.add(sidePane, BorderLayout.WEST);
this.add(menu, BorderLayout.NORTH);
}
}
public class SidePane extends JPanel {
public SidePane() {
FlowLayout f1 = new FlowLayout(FlowLayout.LEADING);
this.setLayout(f1);
this.setBackground(Color.blue);
this.add(content);
}
}
public class Menu extends JPanel {
public Menu() {
this.setBackground(Color.orange);
}
}
public class GlassPane extends JPanel {
private Rectangle target;
public GlassPane() {
this.setOpaque(false);
setLayout(null);
content2.setBackground(Color.BLACK);
content2.setPreferredSize(pSize);
content2.setOpaque(true);
add(content2);
content.addComponentListener(new ComponentAdapter() {
#Override
public void componentResized(ComponentEvent e) {
updateOverlay();
}
#Override
public void componentMoved(ComponentEvent e) {
updateOverlay();
}
});
}
protected void updateOverlay() {
// Rectangle t = new Rectangle();
// t.setBounds((int) content.getLocation().getX(), (int) content.getLocation().getY(), content.getWidth(), content.getHeight());
// Rectangle r = SwingUtilities.convertRectangle(content.getParent(), content.getBounds(), this);
// Rectangle r = SwingUtilities.convertRectangle(content.getParent(), content.getBounds(), this);
target = SwingUtilities.convertRectangle(content.getParent(), content.getBounds(), this);
content2.setBounds(target);
// r = SwingUtilities.convertRectangle(content.getParent(), t, this);
// int x = (int) r.getBounds().getX();
// x = (int) r.getX();
// int y = (int) (r.getY() + r.getHeight());
//
// content2.setBounds(x, y, 100, 100);
// this.add(content2);
}
#Override
public void paint(Graphics g) {
super.paint(g);
Graphics2D g2d = (Graphics2D) g.create();
if (target != null) {
g2d.setColor(Color.RED);
g2d.draw(target);
}
g2d.dispose();
}
}
}
If you have the coordinate within the component, transfer it to screen coordinates using your component's convertPointToScreen(). Afterwards you can transfer back to see where in the window it sits by using the frame's convertPointFromScreen().
Or eliminate one of the two steps by directly using convertPoint().
Fixed the positioning issue using #MadProgrammer 's method of SwingUtilities.convertRectangle and called a new method at the end of the constructor which positioned the tracker panel.
Created a separate class for the glass pane
private class GlassPane extends JPanel {
public GlassPane() {
this.setLayout(null);
}
public void setNewLocation() {
Rectangle r = SwingUtilities.convertRectangle(top, content.getBounds(), this);
JPanel content2 = new JPanel();
int x = (int) r.getBounds().getX();
x = (int) r.getX();
int y = (int) (r.getY() + r.getHeight() + 1);
content2.setBounds(x, y, 100,100);
this.add(content2);
}
}
And added a call to the new method setNewLocation() at the end of the constructor
public test() {
**...**
frame.pack();
frame.setVisible(true);
glass.setNewLocation();
}
Mouse event appears not to work, and i can't find out, why.
I added a debug output at imgEdit.drawDot and there's no output at the console. I'm a newbie in java, so my code may seem to be very bad, as well as my english
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
/**
* Created by doctor on 12/29/15.
*/
public class MainUI {
Window mainWindow;
MainUI() {
mainWindow = new Window();
}
}
class Window extends JFrame {
Window() {
setBounds(0, 0, 600, 400);
setTitle("RebBrush");
Panel mainPanel = new Panel();
Container mainCont = getContentPane();
mainCont.setLayout(null);
mainCont.add(mainPanel);
setVisible(true);
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}
}
class Panel extends JPanel {
private ImageEdit imgEdit;
private JLabel imgLabel;
Panel() {
setLayout(null);
imgEdit = new ImageEdit(600, 400);
imgLabel = new JLabel(new ImageIcon(imgEdit.getImage()));
imgLabel.setBounds(0, 0, 600, 400);
add(imgLabel);
addMouseMotionListener(new MouseMotionListener() {
#Override
public void mouseDragged(MouseEvent e) {
imgEdit.drawDot(e.getX(), e.getY());
}
#Override
public void mouseMoved(MouseEvent e) {
}
});
}
}
Simply getting rid of the null layouts did the trick for me. I'm not sure what ImageEdit is (some other class you've defined?), but by running the following I see "Mouse Dragged" show up in the console, so the mouseDragged method is definitely being called. Just uncomment the imageEdit stuff to put it back in.
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
/**
* Created by doctor on 12/29/15.
*/
public class MainUI {
Window mainWindow;
MainUI() {
mainWindow = new Window();
}
public static void main(String[] args) {
new MainUI();
}
}
class Window extends JFrame {
Window() {
setBounds(0, 0, 600, 400);
setTitle("RebBrush");
Panel mainPanel = new Panel();
Container mainCont = getContentPane();
mainCont.add(mainPanel);
setVisible(true);
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}
}
class Panel extends JPanel {
//private ImageEdit imgEdit;
private JLabel imgLabel;
Panel() {
//imgEdit = new ImageEdit(600, 400);
//imgLabel = new JLabel(new ImageIcon(imgEdit.getImage()));
//imgLabel.setBounds(0, 0, 600, 400);
//add(imgLabel);
addMouseMotionListener(new MouseMotionListener() {
#Override
public void mouseDragged(MouseEvent e) {
System.out.println("Mouse Dragged");
//imgEdit.drawDot(e.getX(), e.getY());
}
#Override
public void mouseMoved(MouseEvent e) {
}
});
}
}
I am trying to remove a JPanel not hide it but i can't find anything that works.
This is the code in the panel that needs to remove itself when a button is pressed:
play.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
Frame frame = new Frame(); //referencing to my JFrame class (this class is a JPanel)
//need to remove this panel on this line
frame.ThreeD(); // adds a new panel
}
});
UPDATED
This is the full code:
package ThreeD;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.UIManager;
import Run.Frame;
public class Launcher extends JPanel{
private JButton play, options, help, mainMenu;
private Rectangle rplay, roptions, rhelp, rmainMenu;
private int buttonWidthLocation, buttonWidth, buttonHeight;
private int width = 1280;
public Launcher() {
this.setLayout(null);
drawButtons();
}
private void drawButtons() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch(Exception e) {
e.printStackTrace();
}
play = new JButton("Play");
options = new JButton("Options");
help = new JButton("Help");
mainMenu = new JButton("Main Menu");
buttonWidthLocation = (width / 2) - (buttonWidth / 2);
buttonWidth = 80;
buttonHeight = 40;
rplay = new Rectangle(buttonWidthLocation, 150, buttonWidth, buttonHeight);
roptions = new Rectangle(buttonWidthLocation, 300, buttonWidth, buttonHeight);
rhelp = new Rectangle(buttonWidthLocation, 450, buttonWidth, buttonHeight);
rmainMenu = new Rectangle(buttonWidthLocation, 600, buttonWidth, buttonHeight);
play.setBounds(rplay);
options.setBounds(roptions);
help.setBounds(rhelp);
mainMenu.setBounds(rmainMenu);
add(play);
add(options);
add(help);
add(mainMenu);
play.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
Frame frame = new Frame();
//need to remove this panel here
frame.ThreeD();
}
});
options.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.out.println("options");
}
});
help.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.out.println("help");
}
});
mainMenu.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.out.println("mainMenu");
}
});
}
}
And this is my Frame class:
package Run;
import javax.swing.*;
import ThreeD.Display;
import ThreeD.Launcher;
import TowerDefence.Window;
import java.awt.*;
import java.awt.image.BufferedImage;
public class Frame extends JFrame{
public static String title = "Game";
/*public static int GetScreenWorkingWidth() {
return java.awt.GraphicsEnvironment.getLocalGraphicsEnvironment().getMaximumWindowBounds().width;
}*/
/*public static int GetScreenWorkingHeight() {
return java.awt.GraphicsEnvironment.getLocalGraphicsEnvironment().getMaximumWindowBounds().height;
}*/
//public static Dimension size = new Dimension(GetScreenWorkingWidth(), GetScreenWorkingHeight());
public static Dimension size = new Dimension(1280, 774);
public static void main(String args[]) {
Frame frame = new Frame();
System.out.println("Width of the Frame Size is "+size.width+" pixels");
System.out.println("Height of the Frame Size is "+size.height+" pixels");
}
public Frame() {
setTitle(title);
setSize(size);
setResizable(false);
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
ThreeDLauncher();
}
public void ThreeDLauncher() {
Launcher launcher = new Launcher();
add(launcher);
setVisible(true);
}
public void TowerDefence() {
setLayout(new GridLayout(1, 1, 0, 0));
Window window = new Window(this);
add(window);
setVisible(true);
}
public void ThreeD() {
BufferedImage cursor = new BufferedImage(16, 16, BufferedImage.TYPE_INT_ARGB);
Cursor blank = Toolkit.getDefaultToolkit().createCustomCursor(cursor, new Point(0, 0), "blank");
getContentPane().setCursor(blank);
Display display = new Display();
add(display);
setVisible(true);
display.start();
}
}
Basically - you are creating new instance of Frame in line:
Frame frame = new Frame(); //referencing to my JFrame class (this class is a JPanel)
New instance of Frame is not visible, and you're try to remove your Launcher from not visible new Frame. But this is wrong - you should remove Launcher from Frame that you created previously in main function (that is: parent of Launcher component).
Here goes an example:
public class TestFrame extends JFrame {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
TestFrame frame = new TestFrame();
frame.getContentPane().add(new MyPanel(frame));
frame.setSize(200, 200);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
});
}
}
And MyPanel class:
public class MyPanel extends JPanel {
public MyPanel(final TestFrame frame) {
JButton b = new JButton("Play");
add(b);
b.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
Container pane = frame.getContentPane();
pane.remove(MyPanel.this);
JPanel otherPanel = new JPanel();
otherPanel.add(new JLabel("OtherPanel"));
pane.add(otherPanel);
pane.revalidate();
}
});
}
}
In your example you should add a reference to Frame in your Launcher constructor:
public Launcher(Frame frame) {
this.frame = frame;
...
Init Launcher:
public void ThreeDLauncher() {
Launcher launcher = new Launcher(this);
and use:
play.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
//need to remove this panel here
frame.getContentPane().remove(Launcher.this);
frame.ThreeD();
}
});
Say your panel is myPanel you can remove it from the main frame by:
frame.getContentPane().remove(myPanel);
I am trying to make a JFrame appear on mousePressed Location but I keep failing and it get's annoying :( Any ideas what isn't working?
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
public class SSCCE
{
#SuppressWarnings("static-access")
public static void getInputData()
{
final JFrame frame = new JFrame();
frame.setDefaultCloseOperation(frame.DISPOSE_ON_CLOSE);
JLabel emptyLabel = new JLabel("Test");
frame.getContentPane().add(emptyLabel, BorderLayout.CENTER);
frame.setSize(new Dimension(375, 100));
MouseAdapter ml = new MouseAdapter()
{
#Override
public void mousePressed(MouseEvent me)
{
frame.setLocation(me.getX(), me.getY());
}
#Override
public void mouseDragged(MouseEvent me)
{
frame.setLocation(me.getX(), me.getY());
}
};
frame.getContentPane().addMouseListener(ml);
frame.getContentPane().addMouseMotionListener(ml);
frame.setVisible(true);
}
public static void main(String args[])
{
JFrame test = new JFrame();
JButton but = new JButton("Click me");
but.addActionListener(
new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
getInputData();
}
});
test.getContentPane().add(but, BorderLayout.CENTER);
test.setSize(500, 500);
test.setVisible(true);
}
}
Use the SwingUtilities methods convertPointToScreen() and convertPointFromScreen() to transform the MouseEvent coordinates.
Addendum: Alternatively, calculate the offset from getLocationOnScreen(), which is "the component's top-left corner in the screen's coordinate space."
Addendum: To position the new frame relative to the original mouse click, add a mouse listener to the parent frame instead of a button; use the coordinates to position the new frame, as shown below.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class SSCCE {
public static void getInputData(MouseEvent e) {
final JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JLabel emptyLabel = new JLabel("Test", JLabel.CENTER);
frame.getContentPane().add(emptyLabel, BorderLayout.CENTER);
frame.setPreferredSize(new Dimension(375, 100));
MouseAdapter ma = new MouseAdapter() {
Point local, global;
Point delta = new Point();
#Override
public void mousePressed(MouseEvent me) {
local = me.getPoint();
}
#Override
public void mouseDragged(MouseEvent me) {
delta.setLocation(
me.getX() - local.x, me.getY() - local.y);
global = frame.getLocationOnScreen();
global.setLocation(
global.x + delta.x, global.y + delta.y);
frame.setLocation(global.x, global.y);
}
};
frame.getContentPane().addMouseListener(ma);
frame.getContentPane().addMouseMotionListener(ma);
frame.pack();
frame.setLocation(e.getLocationOnScreen());
frame.setVisible(true);
}
public static void main(String args[]) {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setPreferredSize(new Dimension(640, 480));
frame.add(new JLabel("Click me", JLabel.CENTER));
frame.addMouseListener(new MouseAdapter() {
#Override
public void mousePressed(MouseEvent e) {
getInputData(e);
}
});
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
Previously,
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class SSCCE {
public static void getInputData() {
final JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JLabel emptyLabel = new JLabel("Test", JLabel.CENTER);
frame.getContentPane().add(emptyLabel, BorderLayout.CENTER);
frame.setPreferredSize(new Dimension(375, 100));
MouseAdapter ma = new MouseAdapter() {
Point local = new Point();
Point delta = new Point();
Point global = new Point();
#Override
public void mousePressed(MouseEvent me) {
local = me.getPoint();
}
#Override
public void mouseDragged(MouseEvent me) {
delta.setLocation(
me.getX() - local.x,
me.getY() - local.y);
global = frame.getLocationOnScreen();
global.setLocation(global.x + delta.x, global.y + delta.y);
frame.setLocation(global.x, global.y);
}
};
frame.getContentPane().addMouseListener(ma);
frame.getContentPane().addMouseMotionListener(ma);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String args[]) {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JButton but = new JButton("Click me");
but.addActionListener(
new ActionListener() {
public void actionPerformed(ActionEvent e) {
getInputData();
}
});
frame.getContentPane().add(but, BorderLayout.CENTER);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
I have created a divider in JSplitPane. I am unable to set the color of divider. I want to set the color of divider. Please help me how to set color of that divider.
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class SplitPaneDemo {
JFrame frame;
JPanel left, right;
JSplitPane pane;
int lastDividerLocation = -1;
public static void main(String[] args) {
SplitPaneDemo demo = new SplitPaneDemo();
demo.makeFrame();
demo.frame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
demo.frame.show();
}
public JFrame makeFrame() {
frame = new JFrame();
// Create a horizontal split pane.
pane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
left = new JPanel();
left.setBackground(Color.red);
pane.setLeftComponent(left);
right = new JPanel();
right.setBackground(Color.green);
pane.setRightComponent(right);
JButton showleft = new JButton("Left");
showleft.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
Container c = frame.getContentPane();
if (pane.isShowing()) {
lastDividerLocation = pane.getDividerLocation();
}
c.remove(pane);
c.remove(left);
c.remove(right);
c.add(left, BorderLayout.CENTER);
c.validate();
c.repaint();
}
});
JButton showright = new JButton("Right");
showright.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
Container c = frame.getContentPane();
if (pane.isShowing()) {
lastDividerLocation = pane.getDividerLocation();
}
c.remove(pane);
c.remove(left);
c.remove(right);
c.add(right, BorderLayout.CENTER);
c.validate();
c.repaint();
}
});
JButton showboth = new JButton("Both");
showboth.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
Container c = frame.getContentPane();
c.remove(pane);
c.remove(left);
c.remove(right);
pane.setLeftComponent(left);
pane.setRightComponent(right);
c.add(pane, BorderLayout.CENTER);
if (lastDividerLocation >= 0) {
pane.setDividerLocation(lastDividerLocation);
}
c.validate();
c.repaint();
}
});
JPanel buttons = new JPanel();
buttons.setLayout(new GridBagLayout());
buttons.add(showleft);
buttons.add(showright);
buttons.add(showboth);
frame.getContentPane().add(buttons, BorderLayout.NORTH);
pane.setPreferredSize(new Dimension(400, 300));
frame.getContentPane().add(pane, BorderLayout.CENTER);
frame.pack();
pane.setDividerLocation(0.5);
return frame;
}
}
Thanks
Sunil kumar Sahoo
Or, since the divider is a container, you can do the following:
dividerContainer = (BasicSplitPaneDivider) splitPane.getComponent(2);
Component leftBtn = dividerContainer.getComponent(0);
Component rightBtn = dividerContainer.getComponent(1);
dividerContainer.setBackground(Color.white);
dividerContainer.setBorder(BorderFactory.createEmptyBorder(0, 4, 0, 4));
dividerContainer.setLayout(new FlowLayout(FlowLayout.CENTER, 0, 0));
dividerContainer.add(toolbar);
dividerContainer.setDividerSize(toolbar.getPreferredSize().height);
This code works for me:
splitPane.setUI(new BasicSplitPaneUI() {
public BasicSplitPaneDivider createDefaultDivider() {
return new BasicSplitPaneDivider(this) {
public void setBorder(Border b) {
}
#Override
public void paint(Graphics g) {
g.setColor(Color.GREEN);
g.fillRect(0, 0, getSize().width, getSize().height);
super.paint(g);
}
};
}
});
splitPane.setBorder(null);
You can change divider color "g.setColor(new Color(R,G,B))".
This worked for me fine.First you are creating JFrame with it's normal methods such as setDefaultCloseOperation(), setBounds(), getContentPane(). Then create an object from your class then use that to call all the other methods through out the program, in this case I created object called app. One thing you have to keep in mind is that don't forget to use ActionListener e.
Also color changes must go with setBackground() function, while you getting the values from getSource() for the color change.
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
public class Main implements ActionListener {
private static void createAndShowGUI() {
Main app=new Main();
// make frame..
JFrame.setDefaultLookAndFeelDecorated(true);
JFrame frame = new JFrame("I am a JFrame");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setBounds(20,30,300,120);
frame.setLayout(null);
//Create a split pane
JSplitPane myPane = new JSplitPane();
myPane.setOpaque(true);
myPane.setDividerLocation(150);
app.right = new JPanel();
app.right.setBackground(new Color(255,0,0));
app.left = new JPanel();
app.left.setBackground(new Color(0,255,0));
app.left.setLayout(null);
myPane.setRightComponent(app.right);
myPane.setLeftComponent(app.left);
// make buttons
app.butt1=new JButton("Red");
app.butt2=new JButton("Blue");
app.butt3=new JButton("Green");
// add and size buttons
app.left.add(app.butt1);
app.butt1.setBounds(10,10, 100,20);
app.left.add(app.butt2);
app.butt2.setBounds(10,30, 100,20);
app.left.add(app.butt3);
app.butt3.setBounds(10,50, 100,20);
// set up listener
app.butt1.addActionListener(app);
app.butt2.addActionListener(app);
app.butt3.addActionListener(app);
frame.setContentPane(myPane);
frame.setVisible(true);
}
public void actionPerformed(ActionEvent e)
{
// check which button and act accordingly
if (e.getSource()==butt1)
right.setBackground(new Color(255,0,0));
if (e.getSource()==butt2)
right.setBackground(new Color(0,0,255));
if (e.getSource()==butt3)
right.setBackground(new Color(0,255,0));
}
public static void main(String[] args) {
// start off..
try {
UIManager.setLookAndFeel(
"javax.swing.plaf.metal.MetalLookAndFeel" );
}
catch (Exception e)
{
System.out.println("Cant get laf");
}
Object a[]= UIManager.getInstalledLookAndFeels();
for (int i=0; i<a.length; i++)
System.out.println(a[i]);
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
// application object fields
int clickCount=0;
JLabel label;
JButton butt1;
JButton butt2;
JButton butt3;
JPanel left;
JPanel right;
}