I'm Trying to choose a color from the JColorChooser via the MouseEventClicked and then set the color chosen to the penColor but for some reason it's not working. I think i have a problem in the MouseClicked function.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
#SuppressWarnings("serial")
public class Paint3<penColor> extends JFrame implements MouseMotionListener, MouseListener, ChangeListener {
int size = 2;
private Point pt = new Point();
private JSlider penSize = new JSlider(JSlider.VERTICAL,1,10,3);
JColorChooser jc = new JColorChooser();
public Color penColor = new Color(0,0,0);
public JPanel DrawingPanel = new JPanel(){
public void paint(Graphics g){
g.fillOval((int) pt.getX(), (int)pt.getY(), 5,5);
}
};
public Paint3(){
super("My Painter");
Label l1 = new Label("Drag Mouse To Draw");
JPanel jp2 = new JPanel();
this.add((DrawingPanel), BorderLayout.NORTH);
DrawingPanel.add((l1),BorderLayout.NORTH);
this.add((jp2),BorderLayout.SOUTH);
jp2.add(jc);
this.addMouseMotionListener(this);
this.addMouseListener(this);
this.add(penSize, BorderLayout.EAST);
penSize.addChangeListener((ChangeListener) this);
penSize.setMinorTickSpacing(1);
penSize.setPaintTicks(true);
setSize(700,700);
setVisible(true);
setDefaultCloseOperation(EXIT_ON_CLOSE);
}
#Override
public void mouseDragged(MouseEvent me){
Graphics2D g = (Graphics2D)getGraphics();
g.setStroke(new BasicStroke(size));
g.setColor(penColor);
g.drawLine(pt.x,pt.y, me.getX(), me.getY());
pt = me.getPoint();
}
#Override
public void mouseMoved(MouseEvent me){
pt = me.getPoint();
}
#Override
public void mouseClicked(MouseEvent me){
if(me.getModifiers()== MouseEvent.BUTTON3_MASK){
//penColor = jc; //(this, "Change Pen Color" , penColor);
//penColor = jc.getColor();
penColor = jc.getColor();
}
}
#Override
public void mouseEntered(MouseEvent me){}
#Override
public void mouseExited(MouseEvent me){}
#Override
public void mousePressed(MouseEvent me){}
#Override
public void mouseReleased(MouseEvent me){}
#Override
public void stateChanged(ChangeEvent me){
JSlider source = (JSlider)me.getSource();
if(!source.getValueIsAdjusting()){
size = (int)source.getValue();
}
}
public static void main(String[] args){
new Paint3();
}
}
Well, just try this code:
#Override
public void mousePressed(MouseEvent me){
penColor = jc.getColor();
}
You will modify the color in the mousePressed and not in the mouseClicked
I hope it will help you, best regards
This is not the way to do it. A MouseListener doesn't work on a javax.swing.JColorChooser the way you expect it to. Alteast not as the way you have mentioned in your post.
You need to import javax.swing.colorchooser.ColorSelectionModel and add a javax.swing.ChangeListener to it.
JColorChooser jc = new JColorChooser();
ColorSelectionModel model = jc.getSelectionModel();
model.addChangeListener(
#Override
public void stateChanged(ChangeEvent event) {
penColor = jc.getColor();
}
);
Related
I am here making a menu for my game where I can press 'Start' button to navigate through the screens. I am trying to implement a seperate button for the class however the way I have laid out the CustomButtons class, it works in a way where I can only make one button which has a function, in order to tackle this issue I decided to make a separate 'Buttons' method which contains the parameters for the button. I have called this within the paint component to ensure that it is being displayed to the screen however only the text 'START' is being displayed to the screen. The background color of the button, the borders, the font etc. isn't being changed alongside the call.
public class CustomButton extends JButton implements MouseListener {
Dimension size = new Dimension(100, 50);
boolean hover = false;
boolean click = false;
boolean isMethodCalled = false;
String text = "";
public CustomButton(String text, Button bb) {
setVisible(true);
setFocusable(true);
setContentAreaFilled(false);
setBorderPainted(false);
this.text = text;
addMouseListener(this);
}
public void Button(Graphics g) {
g.setColor(new Color(255, 255, hover ? 180 : 102 ));
g.fillRect(0, 0, 250, 7);
g.fillRect(0, 0, 7, 150);
g.setColor(Color.ORANGE); // button background color
g.fillRect(14, 14, 222, 122);
g.setColor(Color.WHITE); // text color
g.setFont(Font.decode("arial-BOLD-24"));
FontMetrics metrics = g.getFontMetrics();
int width = metrics.stringWidth(text);
g.drawString(text, 17, 40);
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
Button menu = new Button();
}
public void setButtonText(String text) {
this.text = text;
}
public String getButtonText(String text) {
return text;
}
public void mouseEntered(MouseEvent e) {
hover = true;
}
public void mouseExited(MouseEvent e) {
hover = false;
}
public void mousePressed(MouseEvent e) {
click = true;
}
public void mouseReleased(MouseEvent e) {
click = false;
}
public void mouseClicked(MouseEvent e) {
}
}
Anyone have any idea how I can make it so the button once it is called from the 'Buttons' method works so it is displayed exactly as it should be if all the graphics settings were to be set within the paintComponent method?
This is not what is currently happening. I do not want this to happen:
This is what I want to happen to the button:
To have the custom appearance you need, it's better that your custom button extends JLabel. Below code demonstrates how we can write a custom button by extending JLabel.
This button supports click events. We can add ActionListeners to listen to click events. It changes the background color to brown when user hovers mouse over it.
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
import java.util.List;
public class CustomButton extends JLabel implements MouseListener {
private List<ActionListener> actionListeners = new ArrayList<>();
public CustomButton(String text) {
super(text);
setOpaque(true);
setForeground(Color.white);
setBackground(Color.orange);
setFont(getFont().deriveFont(40.0f));
addMouseListener(this);
}
public void addActionListener(ActionListener listener) {
actionListeners.add(listener);
}
public void removeActionListener(ActionListener listener) {
actionListeners.remove(listener);
}
#Override
public void mouseClicked(MouseEvent e) {
for (ActionListener listener : actionListeners) {
listener.actionPerformed(new ActionEvent(this, 0, "click"));
}
}
#Override
public void mousePressed(MouseEvent e) {
}
#Override
public void mouseReleased(MouseEvent e) {
}
#Override
public void mouseEntered(MouseEvent e) {
setBackground(new Color(185, 122, 87));
}
#Override
public void mouseExited(MouseEvent e) {
setBackground(Color.orange);
}
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setBackground(Color.darkGray);
frame.getContentPane().setLayout(new FlowLayout());
CustomButton customButton = new CustomButton("START");
customButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
JOptionPane.showMessageDialog(frame, "Button clicked");
}
});
frame.getContentPane().add(customButton);
frame.setBounds(300, 200, 400, 300);
frame.setVisible(true);
}
}
I have an undecorated JFrame with JPanel which is for dragging the window on the screen. It works, but when I want to drag it completely to the top of the screen it can't go there. There is space between window and top bar. I'm enclosing the screenshot and code. I'm using Ubuntu 14.04. Is there a way how to fix that?
public class Window extends JFrame {
private int mouse_x_offset;
private int mouse_y_offset;
public Window() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(250, 250);
JPanel panel = new JPanel();
panel.setBackground(Color.BLACK);
setUndecorated(true);
setVisible(true);
panel.addMouseMotionListener(new PanelListener());
panel.addMouseListener(new PanelListener());
add(panel);
}
class PanelListener implements MouseMotionListener, MouseListener {
#Override
public void mouseDragged(MouseEvent e) {
int x = e.getXOnScreen();
int y = e.getYOnScreen();
setLocation(x - mouse_x_offset, y - mouse_y_offset);
}
#Override
public void mouseMoved(MouseEvent e) {
}
#Override
public void mouseClicked(MouseEvent e) {
}
#Override
public void mousePressed(MouseEvent e) {
mouse_x_offset = e.getX();
mouse_y_offset = e.getY();
}
#Override
public void mouseReleased(MouseEvent e) {
}
#Override
public void mouseEntered(MouseEvent e) {
}
#Override
public void mouseExited(MouseEvent e) {
}
}
public static void main(String[] args) {
Window window = new Window();
}
}
Here,is something I wanted to show for the use of MouseEvents of one class in another ...by creating an object of the former class...
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import java.lang.*;
public class MyPagalpanti extends JPanel implements MouseListener
{Point a,b;
boolean drawLin,drawOvl,drawOvl2;
MyPagalpanti(){a=new Point(0,0);b=new Point(0,0);drawLin=false;drawOvl=false,drawOvl2=false;;setSize(300,300);addMouseListener(this);}
public void mouseClicked(MouseEvent m)
{if(!drawOvl){a=new Point(m.getX(),m.getY());drawOvl=true;drawOvl2=false;}
else {b=new Point(m.getX(),m.getY());drawOvl=true;drawOvl2=true;repaint();}//record("clicked",m);}
}
public void mouseEntered(MouseEvent m)
{
}
public void mousePressed(MouseEvent m)
{a=new Point(m.getX(),m.getY());repaint();}
public void mouseReleased(MouseEvent m)
{b=new Point(m.getX(),m.getY());}
public void mouseExited(MouseEvent m)
{}
public void paintComponent(Graphics g)
{if(drawLin){g.setColor(Color.yellow);g.drawLine((int)a.getX(),(int)a.getY(),(int)b.getX(),(int)b.getY());}//d=0;}
else if(drawOvl&&drawOvl2){g.setColor(Color.red);int width=(int)Math.abs(b.getX()-a.getX());
int h=(int)Math.abs(b.getY()-a.getY());
g.drawOval((int)a.getX(),(int)a.getY(),width,h);
}}
}
the class in which an object of MyPagalpanti is formed:
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
//import java.swing.JPanel.*;
public class Mithu extends JFrame// implements MouseListener
{JTextArea jta1,jta2;
Mithu(String title)
{
super(title);
MyPagalpanti p1=new MyPagalpanti();
jta1=new JTextArea();
jta2=new JTextArea();
p1.setOpaque(true);
jta1.setEditable(false);
jta2.setEditable(false);
setForeground(Color.blue);
p1.setPreferredSize(new Dimension(600,600));
p1.setLayout(new GridLayout(3,1,0,0));
getContentPane().add(p1);
pack();
setVisible(true);
}
void record(String s,MouseEvent e)
{jta1.setText(jta1.getText()+"\n"+s+""+e.toString());}
public void mouseClicked(MouseEvent m)
{record("clicked",m);}
public void mouseEntered(MouseEvent m)
{record("entered",m);}
public void mousePressed(MouseEvent m)
{record("pressed",m);}
public void mouseReleased(MouseEvent m)
{ record("released",m);}
public void mouseExited(MouseEvent m)
{record("exited",m);}
public static void main(String args[])
{Mithu m=new Mithu("HI ! Karamvir");
m.setVisible(true);}
}
please don't go word by word...I know my code has many other bugs...coz I am still working on it...but for those who have say that "the MouseEvents will only be delivered to the MouseListener from the component it registered to " ,I guess you are talking correctly but if we see closely, I have used this concept only...in this code..
To add it JBNizet's answer...
MouseListeners will only be delivered to components that are displayable and have registered for notification. Creating a component that is listening for mouse events and adding it you component won't magically make those events delivered to your component.
Then, in top of that, you are adding two components to the default (CENTER) position of a component managed by BorderLayout...
getContentPane().add(panelTop);
//...
getContentPane().add(p1);
This effectively makes the first component invisible, meaning it's not displayable...
You shouldn't be calling show as it's deprecated, use setVisible instead.
You should be calling super.paintComponent in your paintComponent method before doing any custom painting, otherwise you'll end up with no end of painting problems
There is no need for paintComponent to be public as you never want anybody to be able to call it directly...
Updated
Unless you register interest in been notified about events, you will never receive notification, regardless of what objects you create or interfaces you implement.
It's like saying "I'm interested in this movie", but unless you go to the cinemas, you'll never see it...
In order for your Mithu class to receive mouse event notification, it must register a MouseListener against the component that it's interested in monitoring.
The following example registers a a MouseListener in the Mithu class against the instance of MyPagalpanti, which allows it to receive mouse events that are generated by the instance of MyPagalpanti
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class TestMouseListener {
public static void main(String[] args) {
new TestMouseListener();
}
public TestMouseListener() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
Mithu m = new Mithu("HI ! Karamvir");
m.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
m.pack();
m.setLocationRelativeTo(null);
m.setVisible(true);
}
});
}
public class Mithu extends JFrame implements MouseListener
{
JTextArea jta1;
Mithu(String title) {
super(title);
MyPagalpanti p1 = new MyPagalpanti();
p1.addMouseListener(this);
jta1 = new JTextArea();
p1.setOpaque(true);
jta1.setEditable(false);
setForeground(Color.blue);
setLayout(new GridLayout(2, 1));
getContentPane().add(jta1);
getContentPane().add(p1);
pack();
setVisible(true);
}
void record(String s, MouseEvent e) {
jta1.append("\n" + s + "" + e.toString());
}
public void mouseClicked(MouseEvent m) {
record("clicked", m);
}
public void mouseEntered(MouseEvent m) {
record("entered", m);
}
public void mousePressed(MouseEvent m) {
record("pressed", m);
}
public void mouseReleased(MouseEvent m) {
record("released", m);
}
public void mouseExited(MouseEvent m) {
record("exited", m);
}
}
public class MyPagalpanti extends JPanel implements MouseListener {
Point a, b;
boolean drawLin, drawOvl, drawOvl2;
MyPagalpanti() {
a = new Point(0, 0);
b = new Point(0, 0);
drawLin = false;
drawOvl = false;
drawOvl2 = false;
setSize(300, 300);
addMouseListener(this);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(400, 400);
}
public void mouseClicked(MouseEvent m) {
if (!drawOvl) {
a = new Point(m.getX(), m.getY());
drawOvl = true;
drawOvl2 = false;
} else {
b = new Point(m.getX(), m.getY());
drawOvl = true;
drawOvl2 = true;
repaint();
}//record("clicked",m);}
}
public void mouseEntered(MouseEvent m) {
}
public void mousePressed(MouseEvent m) {
a = new Point(m.getX(), m.getY());
repaint();
}
public void mouseReleased(MouseEvent m) {
b = new Point(m.getX(), m.getY());
}
public void mouseExited(MouseEvent m) {
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.RED);
FontMetrics fm = g.getFontMetrics();
if (a != null && b != null) {
g.drawString(a + "-" + b, 0, fm.getHeight());
}
if (drawLin) {
g.setColor(Color.yellow);
g.drawLine((int) a.getX(), (int) a.getY(), (int) b.getX(), (int) b.getY());
}//d=0;}
else if (drawOvl && drawOvl2) {
g.setColor(Color.red);
int width = (int) Math.abs(b.getX() - a.getX());
int h = (int) Math.abs(b.getY() - a.getY());
g.drawOval((int) a.getX(), (int) a.getY(), width, h);
}
}
}
}
Before you go to much further, you really should read through...
Performing Custom Painting
Painting in AWT and Swing
As you are going to have some very nasty suprises if you keep following your current approach.
Also, it wouldn't hurt to read through How to Write a Mouse Listener
Your class has mouseClicked(), mouseReleased() etc. methods, but it doesn't implement MouseListener. And even if it was, it's never added as a MouseListener to any component.
So, make your class implement MouseListener:
public class MouseEvtEx2 extends JFrame implements MouseListener {
and add itself as mouse listener to the component you want to listen to:
panelTop.addMouseListener(this);
And of course, to help yourself read and understand your own code, indent it properly.
I made couple of changes to make it work. you need to implement MouseListener on your MouseEvtEx2 Frame and also you need to add it as the MouseListener to your panel p1
public class MouseEvtEx2 extends JFrame implements MouseListener {
private JTextArea txtArea;
public MouseEvtEx2(String title) {
super(title);
Panel p1 = new Panel();
MyPanel panelTop = new MyPanel();
panelTop.setBackground(new Color(0.98f, 0.97f, 0.85f));
panelTop.setOpaque(true);
panelTop.setPreferredSize(new Dimension(400, 200));
panelTop.setBorder(BorderFactory.createRaisedBevelBorder());
getContentPane().add(panelTop);
txtArea = new JTextArea();
txtArea.setEditable(false);
JScrollPane pane = new JScrollPane(txtArea);
pane.setPreferredSize(new Dimension(400, 200));
p1.setLayout(new GridLayout(2, 1, 0, 0));
getContentPane().add(p1);
p1.addMouseListener(this);
p1.add(pane);
// txtArea.setText
// revalidate();
setSize(600, 600);
show();
}
public void record(String st, MouseEvent et) {
txtArea.setText("" + st + "" + et.toString());
}// setVisible(true);}
public void mouseClicked(MouseEvent evt) {
record("Mouse clicked # of mouse clicks: " + evt.getClickCount(), evt);// +
// " "
// +
}
public void mouseEntered(MouseEvent evt) {
record("Mouse entered ", evt);// .toString());
}
public void mouseExited(MouseEvent evt) {
record("Mouse exited ", evt);// .toString());
}
public void mousePressed(MouseEvent evt) {
record("Mouse pressed # of mouse clicks: ", evt);// .getClickCount() +
// " " +
}
public void mouseReleased(MouseEvent evt) {
record("Mouse released ", evt);
}
public static void main(String[] args) {
new MouseEvtEx2("Mouse events");
}
}
Hope this helps.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
public class Main {
public static void main(String[]args){
#SuppressWarnings("unused")
Gui g = new Gui();
}
}
#SuppressWarnings("serial")
class Gui extends JFrame{
Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
double width = screen.getWidth();
double height = screen.getHeight();
JPanel canvas = new JPanel();
Point mloc = new Point();
JButton br = new JButton("Red");
JButton bb = new JButton("Blue");
JButton bg = new JButton("Green");
JButton wipe = new JButton("Wipe");
JLabel brushwidth = new JLabel("Width = ",JLabel.CENTER);
public JSlider s = new JSlider();
JButton image = new JButton("Image");
Point start = null;
Point current = null;
boolean entered = false;
Color c = Color.red;
public double bwidth = 3;
Gui(){
super("PaintPot");
setSize((int)width/4,(int)height/2);
setVisible(true);
setResizable(false);
setLayout(null);
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
add(s);
s.setSize(getWidth()-20, 20);
s.setLocation(10, 450);
s.setBackground(Color.gray);
s.setForeground(Color.orange);
s.setMajorTickSpacing(50);
s.setMinorTickSpacing(1);
s.setValue((int)bwidth);
s.addChangeListener(new ChangeListener(){
#Override
public void stateChanged(ChangeEvent e) {
bwidth = s.getValue();
brushwidth.setText("Width = "+s.getValue());
}
});
brushwidth.setText("Width = "+s.getValue());
add(brushwidth);
brushwidth.setSize(70,30);
brushwidth.setLocation(90,410);
brushwidth.setBackground(Color.gray);
brushwidth.setForeground(Color.orange);
brushwidth.setOpaque(true);
brushwidth.setVisible(true);
add(wipe);
wipe.setSize(70,30);
wipe.setLocation(10, 410);
wipe.setBackground(Color.gray);
wipe.setForeground(Color.orange);
wipe.setVisible(true);
add(br);
br.setSize(60,30);
br.setLocation(10, 10);
br.setBackground(Color.red);
br.setForeground(Color.white);
br.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent arg0) {
c = Color.red;
}
});
br.setVisible(true);
add(bb);
bb.setSize(60,30);
bb.setLocation(80, 10);
bb.setBackground(Color.blue);
bb.setForeground(Color.white);
bb.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent e) {
c = Color.blue;
}
});
bb.setVisible(true);
add(bg);
bg.setSize(70,30);
bg.setLocation(150, 10);
bg.setBackground(Color.green);
bg.setForeground(Color.white);
bg.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent e){
c = Color.green;
}
});
bg.setVisible(true);
add(image);
image.setSize(70,30);
image.setLocation(230, 10);
image.setBackground(Color.gray);
image.setForeground(Color.orange);
wipe.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent e){
}
});
image.setVisible(true);
canvas(this,canvas);
}
public void canvas(JFrame f, JPanel p){
p.setSize(425,350);
p.setBorder(BorderFactory.createLineBorder(Color.black, 3));
p.setLocation(10, 50);
p.addMouseListener(new MouseListener(){
#Override
public void mouseClicked(MouseEvent arg0) {}
#Override
public void mouseEntered(MouseEvent arg0) {entered = true;}
#Override
public void mouseExited(MouseEvent arg0) {entered = false;}
#Override
public void mousePressed(MouseEvent arg0) {}
#Override
public void mouseReleased(MouseEvent arg0) {}
});
p.addMouseMotionListener(new MouseAdapter(){
public void mouseDragged(MouseEvent e){
mloc = e.getLocationOnScreen();
if(entered = true){
paintComponent(getGraphics());
}
}
});
f.add(p);
}
public void paintComponent(Graphics g){
g.drawOval(mloc.x, mloc.y, (int)bwidth, (int)bwidth);
}
}
I'm trying to get this app to paint inside the JPanel but I can't seem to get it to work,
I want it to draw a line whenever I move my mouse. It's just the public void paint bit I can't get to grips with nothing seem to work.
Thanks
JFrame does not have a paintComponent() method.
Custom painting is done by overriding the paintComponent() method of a JPanel (or JComponent) and then you add the panel to the JFrame.
Read the section from the Swing tutorial on Custom Painting for more information and examples. You will also need to override the getPreferredSize() method.
Also, don't use a null layout. Swing was designed to be used with layout managers.
This if(entered = true){ is an assigment operator not a conditional. Instead you want if(entered == true){
paintComponent is meant to be overriden and not called explicitly. Don't explicitly call paintComponent when what you mean to do is call repaint()
JFrame has no paintComponent method, so you aren't actually overriding any paint functionality. For JFrame you should override paint, though I'd advise against it, and paint with JPanel or JComponent
In a paintComponent or paint method you should also be calling super.paintComponent or super.paint, respectively, as to not break the paint chain.
I have this following class, which refresh a jpeg file in layer 0 and layer 1 is used to draw/paint/sketch up anything related to smash things. But in my drawing when I want to do a thin line, it breaks. Because the mouse cursor movement needs to be slower.
How to resolve on fast mouse move, that the line remains joined?
Annotation.java
package test;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Annotation {
// Image
private static Image backgroundImage;
private static BufferedImage _bufImage = null;
// Enum
public static enum Shape { RECTANGLE, OVAL, LINE }
private static enum State { IDLE, DRAGGING }
private static final Shape INIIIAL_SHAPE = Shape.RECTANGLE;
private static final Color INITIAL_COLOR = Color.RED;
private static Shape _shape = INIIIAL_SHAPE;
private static Color _color = INITIAL_COLOR;
private static State _state = State.IDLE;
private static Point _start = null;
private static Point _end = null;
// JPanel
private static JPanel p;
private static JPanel mp;
/* Run: */
public static void main(String args[]) {
c();
}
/* GUI */
public static void c() {
try {
backgroundImage = ImageIO.read(new File("/var/tmp/test.jpeg"));
} catch (IOException e) {
e.printStackTrace();
}
myTimer();
loadAnnotation();
loadBackground();
JFrame f;
f = new JFrame();
f.setLayout(new BorderLayout());
f.add(mp);
f.pack();
f.setVisible(true);
}
/* 5 seconds to load picture */
public static void myTimer() {
javax.swing.Timer t = new javax.swing.Timer(5000, new ActionListener() {
public void actionPerformed(ActionEvent ae) {
try {
backgroundImage = ImageIO.read(new File("/var/tmp/test.jpeg"));
mp.repaint();
} catch (IOException e) {
e.printStackTrace();
}
}
});
t.start();
}
/* Layer 0:
* Load background picture */
public static void loadBackground() {
mp = new JPanel() {
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(backgroundImage, 0, 0, 1024, 600, null);
}
public Dimension getPreferredSize() {
return new Dimension(1024, 600);
}
};
mp.add(p);
}
/* Layer 1:
* Annotation: Draw on top of background picture anything! */
public static void loadAnnotation() {
p = new JPanel() {
public void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D)g;
g2.setColor(Color.RED);
if (_bufImage == null) {
int w = this.getWidth();
int h = this.getHeight();
_bufImage = new BufferedImage(1024,600, BufferedImage.TRANSLUCENT);
Graphics2D gc = _bufImage.createGraphics();
}
g2.drawImage(_bufImage, null, 0, 0);
if (_state == State.DRAGGING) {
g2.drawLine(_start.x, _start.y, _end.x , _end.y);
}
}
public Dimension getPreferredSize() {
return new Dimension(1024, 600);
}
};
p.setLayout(new FlowLayout());
p.addMouseListener(new MouseListener() {
#Override
public void mouseClicked(MouseEvent me) {
}
#Override
public void mousePressed(MouseEvent me) {
}
#Override
public void mouseReleased(MouseEvent me) {
//_state = State.IDLE;
_state = State.IDLE;
}
#Override
public void mouseEntered(MouseEvent me) {
}
#Override
public void mouseExited(MouseEvent me) {
}
});
p.addMouseMotionListener(new MouseMotionListener() {
#Override
public void mouseDragged(MouseEvent me) {
System.out.println("drag");
_state = State.DRAGGING;
_start = me.getPoint();
_end = _start;
if (_state == State.DRAGGING) {
Graphics2D g2 = _bufImage.createGraphics();
g2.setColor(Color.red);
g2.setStroke(new BasicStroke(90));
g2.fillOval(_start.x, _start.y, 10, 10);
p.repaint();
}
}
#Override
public void mouseMoved(MouseEvent me) {
System.out.println("move");
}
});
JButton pm = new JButton("+");
pm.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent ae) {
}
});
p.add(pm);
p.setOpaque(true);
}
}
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Annotation {
// Image
private static Image backgroundImage;
private static BufferedImage _bufImage = null;
// Enum
public static enum Shape { RECTANGLE, OVAL, LINE }
private static enum State { IDLE, DRAGGING }
private static final Shape INIIIAL_SHAPE = Shape.RECTANGLE;
private static final Color INITIAL_COLOR = Color.RED;
private static Shape _shape = INIIIAL_SHAPE;
private static Color _color = INITIAL_COLOR;
private static State _state = State.IDLE;
private static Point _start = null;
private static Point _end = null;
// JPanel
private static JPanel p;
private static JPanel mp;
/* Run: */
public static void main(String args[]) {
c();
}
/* GUI */
public static void c() {
try {
URL url = new URL("http://pscode.org/media/stromlo2.jpg");
backgroundImage = ImageIO.read(url);
} catch (Exception e) {
e.printStackTrace();
}
loadAnnotation();
loadBackground();
JFrame f;
f = new JFrame();
f.setLayout(new BorderLayout());
f.add(mp);
f.pack();
f.setVisible(true);
}
/* Layer 0:
* Load background picture */
public static void loadBackground() {
mp = new JPanel() {
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(backgroundImage, 0, 0, getWidth(), getHeight(), null);
}
public Dimension getPreferredSize() {
return new Dimension(backgroundImage.getWidth(this), backgroundImage.getHeight(this));
}
};
mp.add(p);
}
/* Layer 1:
* Annotation: Draw on top of background picture anything! */
public static void loadAnnotation() {
p = new JPanel() {
public void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D)g;
g2.setColor(Color.RED);
if (_bufImage == null) {
int w = this.getWidth();
int h = this.getHeight();
_bufImage = new BufferedImage(1024,600, BufferedImage.TRANSLUCENT);
Graphics2D gc = _bufImage.createGraphics();
}
g2.drawImage(_bufImage, null, 0, 0);
if (_state == State.DRAGGING) {
g2.drawLine(_start.x, _start.y, _end.x , _end.y);
}
}
public Dimension getPreferredSize() {
return new Dimension(1024, 600);
}
};
p.setLayout(new FlowLayout());
p.addMouseListener(new MouseListener() {
#Override
public void mouseClicked(MouseEvent me) {
}
#Override
public void mousePressed(MouseEvent me) {
}
#Override
public void mouseReleased(MouseEvent me) {
//_state = State.IDLE;
_state = State.IDLE;
}
#Override
public void mouseEntered(MouseEvent me) {
}
#Override
public void mouseExited(MouseEvent me) {
}
});
p.addMouseMotionListener(new MouseMotionListener() {
#Override
public void mouseDragged(MouseEvent me) {
_state = State.DRAGGING;
_end = me.getPoint();
if (_state == State.DRAGGING) {
Graphics2D g2 = _bufImage.createGraphics();
g2.setColor(Color.red);
g2.setStroke(new BasicStroke(2));
g2.drawLine(_start.x, _start.y, _end.x, _end.y);
p.repaint();
}
_start = _end;
}
#Override
public void mouseMoved(MouseEvent me) {
//System.out.println("move");
_start = me.getPoint();
}
});
JButton pm = new JButton("+");
pm.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent ae) {
}
});
p.add(pm);
p.setOpaque(true);
}
}
I solved this problem by drawing rectangles between points, using the Stroke size (Basic Stroke) for height. It sounds like an icky solution but it does pretty well in reality