I having trouble displaying the x,y coordinates of the mouse on JPopupMenu under mouse pointer. the reason that i use JlayerPane in the code is to be able adding cartesian coordinate system dynamically to the JPopupMenu like what you can see in the CAD application.
Does anyone know why it does not display while it paint correctly?
public void show popupwindow(JPanel parentPanel, int xLocation, int yLocation){
Box selectionBox = createSelectionBox();
JPopupMenu popupMenu = new JPopupMenu();
// create an instance of my custom mouse cursor label
XYMouseLabel mouseLabel = new XYMouseLabel();
mouseLabel.setBounds(0, 0, selectionBox.getWidth(), selectionBox.getHeight());
JPanel panel = new JPanel();
panel.setSize(new Dimension(500, 400));
JLayeredPane layeredPane = new JLayeredPane();
layeredPane.setPreferredSize(new Dimension(400, 300));
layeredPane.setBorder(BorderFactory.createTitledBorder("Move the Mouse to get coordinate"));
layeredPane.addMouseMotionListener(new MouseMotionAdapter() {
#Override
public void mouseMoved(MouseEvent me) {
super.mouseMoved(me);
mouseLabel.x = me.getX();
mouseLabel.y = me.getY();
mouseLabel.repaint();
}
});
layeredPane.add(mouseLabel , JLayeredPane.DRAG_LAYER);
layeredPane.add(selectionBox, 2, 0);
panel.add(layeredPane);
popupMenu.add(panel);
popupMenu.show(parentPanel , xLocation,yLocation)
}
public class XYMouseLabel extends JComponent {
public int x;
public int y;
public XYMouseLabel() {
this.setBackground(Color.green);
}
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
//hier paint the cartesian coordinate system
String s = x + ", " + y;
g2.setColor(Color.red);
g2.drawString(s, x, y);
}
}
Related
I've a class extending JLabel. This JLabel has a particolar shape and I draw that in the method paintComponent. I want to show a text in the center of the jLabel but this text is not shown. Could anyone help me.
My simple HLabel class in the following:
private class Scudetto extends JLabel {
private static final long serialVersionUID = 1L;
public Scudetto(String line_point)
{
super(line_point, SwingUtilities.CENTER);
this.setOpaque(true);
this.setBackground(Color.BLACK);
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Dimension d = this.getSize();
int[] x = { 0, d.width, d.width, d.width / 2, 0 };
int[] y = { 0, 0, d.height / 2, d.height, d.height / 2 };
g.setColor(Color.WHITE);
g.fillPolygon(x, y, 5);
g.setColor(Color.BLACK);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(10, 20);
}
}
I want to show a text in the center of the jLabel but this text is not shown.
The super.paintComponent() will paint the text, but then your custom painting will paint the polygon over top of the text.
Don't override the JLabel. Instead you can create a PolygonIcon. Then you add the Icon and text to the JLabel.
You can have the text centered on the label by using:
JLabel label = new JLabel("your text");
label.setIcon( polygonIcon );
label.setHorizontalTextPosition(JLabel.CENTER);
label.setVerticalTextPosition(JLabel.CENTER);
Here is a simple example of creating a rectangular Icon:
import java.awt.*;
import javax.swing.*;
public class ColorIcon implements Icon
{
private Color color;
private int width;
private int height;
public ColorIcon(Color color, int width, int height)
{
this.color = color;
this.width = width;
this.height = height;
}
public int getIconWidth()
{
return width;
}
public int getIconHeight()
{
return height;
}
public void paintIcon(Component c, Graphics g, int x, int y)
{
g.setColor(color);
g.fillRect(x, y, width, height);
}
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
public static void createAndShowGUI()
{
JPanel panel = new JPanel( new GridLayout(2, 2) );
for (int i = 0; i < 4; i++)
{
Icon icon = new ColorIcon(Color.RED, 50, 50);
JLabel label = new JLabel( icon );
label.setText("" + i);
label.setHorizontalTextPosition(JLabel.CENTER);
label.setVerticalTextPosition(JLabel.CENTER);
panel.add(label);
}
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.getContentPane().add(panel);
f.setSize(200, 200);
f.setLocationRelativeTo( null );
f.setVisible(true);
}
}
I'll let you modify the code for a polygon.
You can also check out Playing With Shapes for some fun ways to create an Icon of different shapes.
So, I have this simple program that allows you to click a JMenu item "New Rectangle" and it adds a shape on the center of the screen. My question is: how can I click-and-drag this around the window? I know I will need some type of Mouse Listener but I'm not sure exactly how to implement it.
public class SimpleDraw {
public static void main(String[] args) {
JFrame frame = new UMLWindow();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setBounds(30, 30, 1000, 700);
frame.getContentPane().setBackground(Color.white);
frame.setVisible(true);
frame.setLocationRelativeTo(null);
// Display the window.
frame.setVisible(true);
}
}
class UMLWindow extends JFrame {
Squares squares = new Squares();
private static final long serialVersionUID = 1L;
public UMLWindow() {
addMenus();
}
public void addMenus() {
getContentPane().add(squares);
JMenuBar menubar = new JMenuBar();
JMenu shapes = new JMenu("Shapes");
JMenuItem rectangleMenuItem = new JMenuItem("New Rectangle");
rectangleMenuItem.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent event) {
squares.addSquare(10, 10, 100, 100);
}
});
shapes.add(rectangleMenuItem);
menubar.add(shapes);
setJMenuBar(menubar);
setDefaultCloseOperation(EXIT_ON_CLOSE);
}
}
class Squares extends JPanel {
private static final long serialVersionUID = 1L;
private List<Rectangle> squares = new ArrayList<Rectangle>();
public void addSquare(int x, int y, int width, int height) {
Rectangle rect = new Rectangle(getWidth() / 2 - width / 2, getHeight()
/ 2 - height / 2, width, height);
squares.add(rect);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
this.setOpaque(true);
this.setBackground(Color.WHITE);
Graphics2D g2 = (Graphics2D) g;
for (Rectangle rect : squares) {
g2.draw(rect);
}
repaint();
}
}
Maybe it can help you :
http://zetcode.com/tutorials/javaswingtutorial/resizablecomponent/
Disadvantage of code
In this code we do not layout manager. So if we have a component in center of jframe when this jframe is re-sizing this component maybe display in corner of jframe. You can solve this problem but it is a little complex. We can talk about this problem if you want.
I wrote a solution for this in this package here. You can see that there is an AreaDragger class, which sounds like what you are looking for
I am trying to paint a rectangle using JPanel. The problem is, when I click on a menu item it should paint a new rectangle. BUT, when I do this, only part of it is painted. Here is what I mean:
rectangleMenuItem.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent event) {
squares.addSquare(10, 10, 100, 100);
}
});
does this:
but when I put the squares.addSquare(...) OUTSIDE of the ActionListener, it gives the correct shape (just not when I want it to)
squares.addSquare(10, 10, 100, 100);
rectangleMenuItem.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent event) {
//nothing on click...
}
});
and here is the correct rectangle:
any idea why it doesn't draw correctly when I put it in the ActionListener? Thanks.
Full Code
class UMLWindow extends JFrame {
Squares squares = new Squares();
private static final long serialVersionUID = 1L;
public UMLWindow() {
addMenus();
}
public void addMenus() {
getContentPane().add(squares);
//squares.addSquare(10, 10, 100, 100);
JMenuBar menubar = new JMenuBar();
JMenu file = new JMenu("File");
file.setMnemonic(KeyEvent.VK_F);
JMenu shapes = new JMenu("Shapes");
file.setMnemonic(KeyEvent.VK_F);
JMenuItem rectangleMenuItem = new JMenuItem("New Rectangle");
rectangleMenuItem.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent event) {
squares.addSquare(10, 10, 100, 100);
}
});
shapes.add(rectangleMenuItem);
menubar.add(shapes);
setJMenuBar(menubar);
setTitle("UML Editior");
setSize(300, 200);
setLocationRelativeTo(null);
}
}
class Squares extends JPanel {
private static final long serialVersionUID = 1L;
private List<Rectangle> squares = new ArrayList<Rectangle>();
public void addSquare(int x, int y, int width, int height) {
Rectangle rect = new Rectangle(x, y, width, height);
squares.add(rect);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
this.setOpaque(true);
this.setBackground(Color.WHITE);
Graphics2D g2 = (Graphics2D) g;
for (Rectangle rect : squares) {
g2.draw(rect);
}
}
}
Swing uses a passive rendering engine, so it doesn't know when it should update/repaint a component unless you tell it.
Start by calling repaint from within your addSquare method...
public void addSquare(int x, int y, int width, int height) {
Rectangle rect = new Rectangle(x, y, width, height);
squares.add(rect);
repaint();
}
This will make a request to the repaint manager informing it the current component needs to be repainted.
You should also be providing a sizing hint for your component, so layout managers to set it's size to 0x0.
Consider overriding the getPreferredSize method of the Squares class and return an appropriate default size...
#Override
public Dimension getPreferredSize() {
return new Dimension(300, 200);
}
This will also mean that you can call pack on the main window and it will "pack" itself around the content, very neat.
Also, don't call methods which will either change the state of the component or other components or schedule an additional repaint request, as this could setup an infinite loop of repaints which will drain your PC of resources....
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
// This is bad...
//this.setOpaque(true);
// This is bad...
//this.setBackground(Color.WHITE);
Graphics2D g2 = (Graphics2D) g;
for (Rectangle rect : squares) {
g2.draw(rect);
}
}
Things like opacity and color should be defined outside of the paint cycle. Also, components that extend from JPanel are opaque by default ;)
I am currently writing a Java painting program using the Swing libraries and Graphics2D to paint. My main GUI class extends JComponent, and I am trying to put it inside a JPanel, and the JPanel inside a JFrame, in order to show it on the screen. When starting up the program though, the JComponent appears to be just a black line (the border, which is set to be a black line around the component). I cannot see why this is happening, and I've been debugging it for hours. If somebody could find the error in this program, I'd be very happy. Thanks in advance.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class PaintGUI extends JComponent {
private static final long serialVersionUID = 1L;
JButton red, green, blue, clear;
Image img;
Graphics2D gfx;
JFrame drawFrame;
JPanel btnPan, drawPan;
MyListener ml;
Action act;
int x, y, prevX, prevY;
public PaintGUI(){
//Initialisering av panel, frame og content
drawFrame = new JFrame("IFIPaint");
drawFrame.setLayout(new BorderLayout());
btnPan = new JPanel();
drawPan = new JPanel();
btnPan.setLayout(new FlowLayout());
drawPan.setLayout(new BorderLayout());
this.setEnabled(true);
//Setter størrelser
btnPan.setPreferredSize(new Dimension(30, 60));
btnPan.setMinimumSize(new Dimension(30, 60));
btnPan.setMaximumSize(new Dimension(30, 60));
//Ordner knappene
red = new JButton("Rød");
green = new JButton("Grønn");
blue = new JButton("Blå");
clear = new JButton("Slett alt");
//Putter knappene på panelet
btnPan.add(red);
btnPan.add(green);
btnPan.add(blue);
btnPan.add(clear);
//Legger på action listeners
act = new Action();
red.addActionListener(act);
green.addActionListener(act);
blue.addActionListener(act);
clear.addActionListener(act);
//Fullfører vindu og setter synlighet
drawFrame.setSize(500, 500);
drawPan.setBounds(0, 0, 400, 400);
this.setBounds(0, 0, 400, 400);
drawPan.add(this);
this.setBackground(Color.RED);
drawFrame.add(drawPan, BorderLayout.NORTH);
drawFrame.add(btnPan, BorderLayout.SOUTH);
this.setBorder(BorderFactory.createLineBorder(Color.BLACK));
this.setVisible(true);
drawPan.setVisible(true);
btnPan.setVisible(true);
drawFrame.setVisible(true);
this.paintComponent(gfx);
drawFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
draw();
}
public void draw() {
ml = new MyListener();
this.addMouseListener(ml);
this.addMouseMotionListener(ml);
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
if(img == null){
img = createImage(this.getWidth(),this.getHeight());
gfx = (Graphics2D) img.getGraphics();
gfx.setPaint(Color.RED);
gfx.fillRect(0, 0, this.getSize().width, this.getSize().height);
gfx.setPaint(Color.RED);
gfx.dispose();
}
gfx.drawImage(img, 0, 0, this);
}
class Action implements ActionListener {
public void actionPerformed(ActionEvent e) {
if(e.getSource() == red){
gfx.setPaint(Color.RED);
repaint();
} else if (e.getSource() == green){
gfx.setPaint(Color.GREEN);
repaint();
} else if (e.getSource() == blue) {
gfx.setPaint(Color.BLUE);
repaint();
} else if (e.getSource() == clear) {
gfx.clearRect(0, 0, drawFrame.getWidth(), drawFrame.getHeight());
repaint();
}
}
}
class MyListener extends MouseAdapter {
public void mousePressed(MouseEvent e) {
prevX = e.getX();
prevY = e.getY();
System.out.println("o ye");
}
public void mouseDragged(MouseEvent e) {
x = e.getX();
y = e.getY();
gfx.drawLine(prevX, prevY, x, y);
repaint();
prevX = x;
prevY = y;
}
}
}
You added the PaintGUI to frame but LayoutManager don't know the size and can't set desired size.
Either set the preferred size (or override getPreferredSize to return desired size)
or add to the PaintGUI instance some component(s) with preferred size (e.g. buttons)
Ok i have a JPanel such as this one :
public class GUI {
JFrame frame = new JFrame("Net");
JPanel panel = new JPanel();
public GUI()
{
frame.setSize(835,650);
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.setVisible(true);
frame.add(panel);
panel.setSize(600,600);
panel.setLocation(215,5);}
There are some other panels in there tables etc. My main is this one :
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable(){
#Override
public void run(){
//new GUI();
new GUI().buildTable();
}
});
And there i another class this one :
public class DrawPlanes extends GUI
{
private static int centreX, centreY, radius;
private Color colour;
public DrawPlanes()
{
centreX = 300;
centreY = 300;
radius = 200;
colour = Color.BLACK;
}
public DrawPlanes(int centreX,int centreY, int radius, Color colour)
{
this.centreX = centreX;
this.centreY = centreY;
this.radius = radius;
this.colour = colour;
}
#Override
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
System.out.println("ppp");
Graphics2D g2D = (Graphics2D) g;
g2D.setStroke(new BasicStroke(2F));
g.setColor(Color.BLACK);
g.drawOval(centreX - radius , centreY - radius, radius * 2 , radius * 2);
......
}
}
Now i cant add this class to my panel i tried creating an object in main and then adding the object to my panel. I ve also tried
panel.add(new DrawPlanes(int x, int y, int radius,Color colour));
but it didnt get the drawing added in the panel.Any suggestions?
DrawPanel is not a component, it extends GUI which is not a component either.
container.add(component) function expects a Component, in Swing essentially JComponent and it's extending component: JPanel, JLabel, JButton etc.
extends DrawPanel to a JComponent or JPanel. However they both are basically some other than the fact that JComponent is non-opaque while JPanel is opaque.