Show polygon's coordinates in JPanel java - java

I am new to java and i am trying to draw some lines one after another. When i right clik, the (kind of) polygon ends and then starts another one with the next (left) click. I wanna show in a JLabel the coordinates ofeach point of these polygons. It should look(foe example) like this
The coordinates should be shown only when the "Ausgabe" button is clicked. I tried to save the coordinates in a list, but i don't know how to show it in a JLabel. Here is my code until now.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.awt.geom.*;
import java.util.ArrayList;
import java.util.List;
class MousePanel extends JPanel implements MouseListener,ActionListener{
private int x,y,x2,y2,a=1;
Point2D p= new Point2D.Double(x,y);
public final List <Point2D> coordinates= new ArrayList <Point2D>();
public final String listString= coordinates.toString();
public MousePanel(){
super();
addMouseListener(this);
}
public void paint(Graphics g){ // draws the lines
Graphics2D g2d= (Graphics2D) g;
GeneralPath gp = new GeneralPath ();
gp.moveTo (x,y);
gp.lineTo(x2,y2);
g2d.draw(gp);
}
public void mousePressed(MouseEvent mouse){
if (SwingUtilities.isLeftMouseButton(mouse)){ // if left mouse button is clicked
if (a == 1) { // the lines ar one after the another
a = 0; // set the first click coordinates
x = x2 = mouse.getX();
y = y2 = mouse.getY();
coordinates.add(p); // saves the coordinates in the list
}
else {
x = x2;
y = y2;
x2 = mouse.getX();
y2 = mouse.getY();
repaint();
coordinates.add(p);
}}
else { // if right mouse button is clicked
a = 1; // --> new polygon/ line
x = x2;
y = y2;
x2 = mouse.getX();
y2 = mouse.getY();
repaint();
coordinates. add(p);
}
}
public void mouseEntered(MouseEvent mouse){ }
public void mouseExited(MouseEvent mouse){ }
public void mouseClicked(MouseEvent mouse){ }
public void mouseReleased(MouseEvent mouse){ }
#Override
public void actionPerformed(ActionEvent arg0) {
// TODO Auto-generated method stub
}
}
class MyGui extends JFrame implements ActionListener {
JLabel label = new JLabel ("<html>First line<br>Second line</html>");
public void createGUI() { // creates the frame
setTitle("Monica's first GUI");
setLocationRelativeTo(null);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setSize(500, 700);
JPanel container = (JPanel) getContentPane();
container.setLayout(null);
label.setBounds(0,430,500,130);
label.setBackground(Color.white);
label.setOpaque(true);
getContentPane().add(label);
JButton go = new JButton("Beenden"); // creates and adds the buttons
go.setBounds(250,580,130,40);
container.add(go);
go.addActionListener(this);
JButton go2 = new JButton("Ausgabe");
go2.setBounds(100,580,130,40);
container.add(go2);
go2.addActionListener(this);
JMenuBar menubar=new JMenuBar(); // creates the menu
JMenu menu=new JMenu("Menu");
JMenuItem exit=new JMenuItem("Exit");
JMenuItem reset=new JMenuItem ("Reset");
JMenuItem ausgabe= new JMenuItem ("Ausgabe2");
menu.add("Save");
menu.add(reset);
JMenu edit= new JMenu ("Edit");
menu.add(edit);
edit.add("Copy");
edit.add("Cut");
edit.add("Paste");
menu.add(exit);
menu.add(ausgabe);
menubar.add(menu);
setJMenuBar(menubar);
exit.addActionListener(this);
reset.addActionListener(this);
ausgabe.addActionListener(this);
}
public void actionPerformed(ActionEvent e) // the buttons respond when clicked
{
if(e.getActionCommand()=="Beenden")
{
System.exit(0);
}
if(e.getActionCommand()=="Ausgabe")
{
}
if(e.getActionCommand()=="Exit")
{
System.exit(0);
}
if (e.getActionCommand()=="Reset") // clears the JPanel
{
getContentPane().repaint();
label.setText("");
}
}
}
public class MyFirstGui {
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
MyGui myGUI = new MyGui();
myGUI.createGUI();
MousePanel panel = new MousePanel();
panel.setBounds(0,0,500,430);
myGUI.getContentPane().add(panel);
myGUI.setVisible(true);
}
});
}
}
Any help???

So for this to work, you need to change a couple things about your code. The first thing is, to either make your coordinates ArrayList public static
public static final List <Point2D> coordinates= new ArrayList <Point2D>();
or to pass the instance of MousePanel you are creating to MyGui.
public class MyFirstGui {
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
MousePanel panel = new MousePanel();
panel.setBounds(0,0,500,430);
MyGui myGUI = new MyGui(panel);
myGUI.createGUI();
myGUI.getContentPane().add(panel);
myGUI.setVisible(true);
}
});
}
}
You then store this instance locally in your MyGui.
class MyGui extends JFrame implements ActionListener {
private MousePanel storedMousePanel;
public MyGui(MousePanel mousePanel) {
this.storedMousePanel = mousePanel;
}
}
Next you can use either the stored instance or the static List to access your coordinates. To print them out the way you wanted, we can use a for-loop to iterate through the List and then just add all the coordinates up to one large string.
public void actionPerformed(ActionEvent e) // the buttons respond when clicked
{
if (e.getActionCommand()=="Beenden") {
...
}
else if(e.getActionCommand()=="Ausgabe")
{
getContentPane().repaint();
String labelText = "";
//Using the static List
for (int i = 0; i < MousePanel.coordinates.size(); i++) {
labelText += "(" + String.valueOf(MousePanel.coordinates.get(i).getX()) + ")(" + String.valueOf(MousePanel.coordinates.get(i).getY()) + ")\n";
}
//Using the stored instance
for (int i = 0; i < storedMousePanel.coordinates.size()) {
labelText += "(" + String.valueOf(storedMousePanel.coordinates.get(i).getX()) + ")(" + String.valueOf(storedMousePanel.coordinates.get(i).getY()) + ")\n";
}
label.setText(labelText);
}
else if(e.getActionCommand()=="Exit")
{
System.exit(0);
}
else if (e.getActionCommand()=="Reset") // clears the JPanel
{
getContentPane().repaint();
label.setText("");
}
}

Related

How do I draw string from user input in a JFrame Java

Couldn't find what I was looking for from the search function, I might have just been formulating the title badly.
Anyways, right now I can click on my JFrame and it will draw whatever the user types into the console and when you hit Enter it will stop the sentence.
But what I want is for the user to just type directly into the JFrame and then when you hit enter you end the input.
This is what I have now:
public void drawString(MouseEvent e) throws IOException {
if(textClick==true) {
int xLoc = e.getX();
int yLoc = e.getY();
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String accStr;
System.out.println("Enter your Account number: ");
accStr = br.readLine();
g2.drawString(accStr, xLoc, yLoc);
textClick=false;
}
}
So you click somewhere on the JFrame. It will then display whatever the user is typing at that location, without having to go into the console and type there.
Don't mix console input with a Swing GUI as this can lead to a threading nightmare. Instead get the input by some other means. Myself, I'd use a JOptionPane.showInputDialog(...) to get a user's input String. Also, don't use Graphics like you're doing outside of a paint or paintComponent method as that's a recipe for a NullPointerException or some other GUI failure. Instead display the text in a JLabel or a text component such as a JTextArea or JTextField.
Something like:
public void drawString(MouseEvent e) throws IOException {
if(textClick) { // none of this == true stuff please
int xLoc = e.getX();
int yLoc = e.getY();
String prompt = "Enter your Account Number:";
String input = JOptionPane.showInputDialog(someComponent, prompt);
// !!! no
// g2.drawString(accStr, xLoc, yLoc); // no don't do this
myJLabel.setText(input);
textClick=false;
}
}
If you absolutely must draw the String using Graphics, then in the method above, set a field of the object, perhaps something like private String textToDraw, call repaint() on your GUI, and in your JPanel's protected void paintComponent(Graphics g) method draw the text.
Here's a kludge code that puts a JTextField at the mousepressed location, and then converts the JTextField into a JLabel either on enter press or on focus lost:
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.*;
public class AddingText extends JPanel {
private static final int PREF_W = 500;
private static final int PREF_H = PREF_W;
public AddingText() {
addMouseListener(new MyMouse());
setLayout(null); // one of the few times this may be ok
}
#Override
public Dimension getPreferredSize() {
if (isPreferredSizeSet()) {
return super.getPreferredSize();
}
return new Dimension(PREF_W, PREF_H);
}
private void convertToLabel(final JTextField textField) {
JLabel label = new JLabel(textField.getText());
label.setSize(label.getPreferredSize());
label.setLocation(textField.getLocation());
remove(textField);
add(label);
repaint();
}
private class MyMouse extends MouseAdapter {
#Override
public void mousePressed(MouseEvent e) {
final JTextField textField = new JTextField(20);
textField.setSize(textField.getPreferredSize());
textField.setLocation(e.getPoint());
add(textField);
revalidate();
repaint();
textField.requestFocusInWindow();
textField.addFocusListener(new FocusAdapter() {
#Override
public void focusLost(FocusEvent e) {
convertToLabel((JTextField) e.getComponent());
}
});
textField.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
convertToLabel((JTextField) e.getSource());
}
});
}
}
private static void createAndShowGui() {
AddingText mainPanel = new AddingText();
JFrame frame = new JFrame("AddingText");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
Attempt two: where I draw directly in the JPanel by overridding paintComponent and by using a JOptionPane. The text is placed into a Map<Point, String> and then this text is drawn within paintComponent by iterating through this map. This way we avoid the dreaded null layout.
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.LinkedHashMap;
import java.util.Map;
import javax.swing.*;
public class AddingText2 extends JPanel {
private static final int PREF_W = 500;
private static final int PREF_H = PREF_W;
private Map<Point, String> pointTextMap = new LinkedHashMap<>();
public AddingText2() {
addMouseListener(new MyMouse());
}
#Override
public Dimension getPreferredSize() {
if (isPreferredSizeSet()) {
return super.getPreferredSize();
}
return new Dimension(PREF_W, PREF_H);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setFont(getFont().deriveFont(Font.BOLD));
for (Point p : pointTextMap.keySet()) {
String text = pointTextMap.get(p);
g.drawString(text, p.x, p.y);
}
}
private class MyMouse extends MouseAdapter {
#Override
public void mousePressed(MouseEvent e) {
String prompt = "Please add text to display";
String input = JOptionPane.showInputDialog(AddingText2.this, prompt);
pointTextMap.put(e.getPoint(), input);
repaint();
}
}
private static void createAndShowGui() {
AddingText2 mainPanel = new AddingText2();
JFrame frame = new JFrame("AddingText2");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
If i understood your problem right, you basicly want a KeyListener:
public class MyWindow extends JFrame {
private int x, y;
private String text;
private boolean shouldGetText = false;
private KeyListener keyboard = new KeyAdapter() {
public void keyTyped(KeyEvent evt) {
if(!shouldGetText)
return;
text = text + evt.getChar(); // or evt.getKeyChar()... not sure about the name of this method
}
public void keyPressed(KeyEvent evt) {
if (shouldGetText && evt.getKeyCode() == KeyEvent.VK_ENTER)
shouldGetText = false;
}
}
private MouseListener mouse = new MouseAdapter() {
public void mouseMoved(MouseEvent evt) {
if (shouldGetText)
return;
x = evt.getX();
y = evt.getY();
}
public void mousePressed(MouseEvent evt) {
shouldGetText = true;
text = "";
}
}
public MyWindow() {
addKeyListener(keyboard);
addMouseListener(mouse);
addMouseMotionListene(mouse);
// Do other stuff
}
#Override
public void paint(Graphics g) {
super.paint(g);
g.drawString(text, x, y);
}
}

Doing an animation in Java

I am doing a java assignment for next Saturday.
Its going really well, however I'm struggling with one section.
Here I want to reveal a set of numbers in a String, one at a time.
I tried slowing down the loop with 'Thread.sleep(1000);'
however nothing is displaying until the thread is finished
the following is a section of the graphics class where the problem is occuring
is there something I'm missing?
public void paint(Graphics g)
{
setSize(550, 300);
//this draws all the random numbers, revealing the ans to the user
if (revealNum == 0)
{
g.setColor(Color.BLUE);
g.drawString(randomNumber, 20, 20); //draw String ("the String", x, y)
}
//this reveals the numbers 1 by 1 to the user at the start of the game
if (revealNum==1)
{
for (int x = 0; x < limit; x++)
{
g.setColor(Color.BLUE);
g.drawString(""+x, 20, 20); //draw String ("the String", x, y)
try{
Thread.sleep(1000);
}catch(InterruptedException ex){
System.out.print("Error");
}
repaint();
}
//slow down the loop to show the user
}
Since yours is a GUI, calling Thread.sleep will put the entire app to sleep. Instead use a Swing Timer. Inside the Timer's ActionListener, add another letter to the displayed String, and then stop the Timer via the stop() method once the String is complete.
e.g.,
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import javax.swing.*;
public class SimpleAnimation extends JPanel {
public static final int TIMER_DELAY = 1000;
private JTextField textField = new JTextField(10);
private JLabel displayLabel = new JLabel("", SwingConstants.CENTER);
public SimpleAnimation() {
Action btnAction = new DoItBtnAction("Do It!", KeyEvent.VK_D);
JPanel topPanel = new JPanel();
topPanel.add(textField);
topPanel.add(new JButton(btnAction));
textField.addActionListener(btnAction);
setLayout(new GridLayout(2, 1));
add(topPanel);
add(displayLabel);
}
private class DoItBtnAction extends AbstractAction {
private String textFieldText = "";
public DoItBtnAction(String name, int mnemonic) {
super(name);
putValue(MNEMONIC_KEY, mnemonic);
}
#Override
public void actionPerformed(ActionEvent e) {
displayLabel.setText("");
setEnabled(false);
textFieldText = textField.getText();
new Timer(TIMER_DELAY, new ActionListener() {
private int i = 0;
#Override
public void actionPerformed(ActionEvent e) {
if (i >= textFieldText.length()) {
((Timer) e.getSource()).stop();
DoItBtnAction.this.setEnabled(true);
} else {
displayLabel.setText(displayLabel.getText() + textFieldText.charAt(i));
i++;
}
}
}).start();
}
}
private static void createAndShowGui() {
JFrame frame = new JFrame("SimpleAnimation");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new SimpleAnimation());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
Also,
If yours is a Swing GUI, it would be easier to display your text in a JLabel or a JTextField rather than trying to paint it on the GUI.
If this is Swing, don't override paint(Graphics g) but rather the paintComponent(Graphics g) method of a JPanel or JComponent.
You should use a javax.swing.Timer
Here is an example
JLabel l = ...;
Timer t = new Timer(1000, new ActionListener() {
public void actionPerformed(ActionEvent ae) {
if (l.getText().equals("1")) l.setText("2");
else if (l.getText().equals("2)) l.setText("1");
}
});

how to pass value to rotate method on menu item click?

i am developing application of rotating image.
as user click menu item as per that image should be rotate.
right now i have implemented keyboard listener, in which as user press right to left button it moves but i want to change that method and want as per menu item click.
right now it passes degrees variable to method rotate, now i want to custom that and as user click menu item it pass the value.
i don't know how to do.
my code:
public class RotateIMGn extends JPanel {
private static final long serialVersionUID = 1L;
ImageIcon image = new ImageIcon("D://Workspace//ScaleImage//src//images//img.png");
JLabel label = new JLabel(image);
JPanel rotationPanel;
final int WIDTH = 350;
final int HEIGHT = 500;
double degrees;
public RotateIMGn() {
setPreferredSize(new Dimension(446, 500));
setFocusable(true);
addKeyListener(new KeyboardListener());
rotationPanel = new JPanel();
rotationPanel = new turningCanvas();
rotationPanel.setPreferredSize(new Dimension(image.getIconWidth(), image.getIconHeight()));
add(rotationPanel);
JMenuBar menuBar = new JMenuBar();
add(menuBar);
JMenu mnFile = new JMenu("Rotate");
menuBar.add(mnFile);
ImageIcon icon90 = createImageIcon("/images/images_Right.png");
JMenuItem mntmTR90 = new JMenuItem("Rotate 90+", icon90);
mntmTR90.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
try {
} catch (Exception e) {
e.printStackTrace();
}
}
});
mnFile.add(mntmTR90);
ImageIcon icon180 = createImageIcon("/images/images_Vertical.png");
JMenuItem mntmRT180 = new JMenuItem("Rotate 180+", icon180);
mnFile.add(mntmRT180);
JSeparator separator = new JSeparator();
mnFile.add(separator);
ImageIcon micon90 = createImageIcon("/images/images_Left.png");
JMenuItem mntmTRM90 = new JMenuItem("Rotate 90-", micon90);
mnFile.add(mntmTRM90);
ImageIcon micon180 = createImageIcon("/images/images_Horizontal.png");
JMenuItem mntmRTM180 = new JMenuItem("Rotate 180-", micon180);
mnFile.add(mntmRTM180);
rotationPanel.setBounds(WIDTH / 2, HEIGHT / 2,
rotationPanel.getPreferredSize().width,
rotationPanel.getPreferredSize().height);
degrees = 0;
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
}
public class turningCanvas extends JPanel {
private static final long serialVersionUID = 1L;
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.rotate(Math.toRadians(degrees), image.getIconWidth() / 2,
image.getIconHeight() / 2);
image.paintIcon(this, g2d, 0, 0);
}
}
public class KeyboardListener implements KeyListener {
public void keyPressed(KeyEvent event) {
if (event.getKeyCode() == KeyEvent.VK_LEFT) {
degrees--;
repaint();
}
if (event.getKeyCode() == KeyEvent.VK_RIGHT) {
degrees++;
repaint();
}
}
public void keyTyped(KeyEvent event) {
}
public void keyReleased(KeyEvent event) {
}
}
public static void main(String[] args) {
RotateIMGn test = new RotateIMGn();
JFrame frame = new JFrame();
frame.setContentPane(test);
frame.pack();
frame.setVisible(true);
}
protected static ImageIcon createImageIcon(String path) {
java.net.URL imgURL = RotateIMGn.class.getResource(path);
if (imgURL != null) {
return new ImageIcon(imgURL);
} else {
System.err.println("Couldn't find file: " + path);
return null;
}
}
}
anyone's idea will help me a lot so...
Use Swing Actions for the menu items instead of Strings. Then, in the actionPerformed method, update the degreesvariable, as you do your KeyListener.
Something like:
ImageIcon icon90 = createImageIcon("/images/images_Right.png");
JMenuItem mntmTR90 = new JMenuItem(new AbstractAction("Rotate 90+", icon90) {
public void actionPerformed(ActionEvent e) {
degrees += 90;
repaint();
}
});

Problem with extending class JLabel to add to it property dragging

I have class JLabelExtended, which extends class javax.swing.JLabel.
I extend it, because I want to add property dragging using mouse.
Here is my code:
public class JLabelExtended extends JLabel {
private MouseMotionAdapter mouseMotionAdapter;
private JLabelExtended jLabelExtended;
public LabelEasy(String text) {
super(text);
jLabelExtended = this;
mouseMotionAdapter = new MouseMotionAdapter() {
#Override
public void mouseDragged(MouseEvent e) {
System.out.println(e.getX() + " : " + e.getY());
jLabelExtended.setLocation(e.getX(), e.getY()
);
}
};
jLabelExtended.addMouseMotionListener(mouseMotionAdapter);
}
}
This is console part after label dragged:
163 : 163
144 : -87
163 : 162
144 : -88
163 : 161
144 : -89
I have several questions:
Why e.getY() takes negative results?
When I drag my label there are appeares copy of label which drags near my label. How can I fix it?
When I drag my label, it drags very slowly.For example: when I move my cursor on 10 points my label moves only on 5 point. How can I fix it?
Thanks in advance
Here are else one way to extend JLabel:
public class LabelEasy extends JLabel {
private MouseAdapter moveMouseAdapter;
private MouseMotionAdapter mouseMotionAdapter;
private LabelEasy jLabelExtended;
private int xAdjustment, yAdjustment;
Boolean count = false;
public LabelEasy(String text) {
super(text);
jLabelExtended = this;
moveMouseAdapter = new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
if (e.getButton() == 1) {
xAdjustment = e.getX();
yAdjustment = e.getY();
}
}
};
mouseMotionAdapter = new MouseMotionAdapter() {
#Override
public void mouseDragged(MouseEvent e) {
if (count) {
System.out.println(e.getX() + " : " + e.getY());
jLabelExtended.setLocation(xAdjustment + e.getX(), yAdjustment + e.getY());
count = false;
} else {
count = true;
}
;
}
};
jLabelExtended.addMouseMotionListener(mouseMotionAdapter);
jLabelExtended.addMouseListener(moveMouseAdapter);
}
}
But it works like previous variant.
I think you're doing it wrong. The MouseMotionListener is added to the JLabel and its location is relative to the JLabel, not the Container which holds the JLabel, so the information is useless to help you drag it. You may wish to use a MouseAdapter and add it both as a MouseListener and a MouseMotionListener. On mousePressed, get the location of the JLabel and the mouse relative to the screen and then use that for your dragging on mouseDragged. Myself, I wouldn't extend JLabel to do this but would rather just use a regular JLabel, but that's my preference.
Edit: it worked better for me when I dealt with the mouse's position relative to the screen (by calling getLocationOnScreen) and the JLabel's position relative to its Container (by calling getLocation). For e.g.,
import java.awt.*;
import java.awt.event.*;
import java.util.Random;
import javax.swing.*;
public class DragLabelEg {
private static final String[] LABEL_STRINGS = { "Do", "Re", "Me", "Fa",
"So", "La", "Ti" };
private static final int HEIGHT = 400;
private static final int WIDTH = 600;
private static final Dimension MAIN_PANEL_SIZE = new Dimension(WIDTH,
HEIGHT);
private static final int LBL_WIDTH = 60;
private static final int LBL_HEIGHT = 40;
private static final Dimension LABEL_SIZE = new Dimension(LBL_WIDTH,
LBL_HEIGHT);
private JPanel mainPanel = new JPanel();
private Random random = new Random();
public DragLabelEg() {
mainPanel.setPreferredSize(MAIN_PANEL_SIZE);
mainPanel.setLayout(null);
MyMouseAdapter myMouseAdapter = new MyMouseAdapter();
for (int i = 0; i < LABEL_STRINGS.length; i++) {
JLabel label = new JLabel(LABEL_STRINGS[i], SwingConstants.CENTER);
label.setSize(LABEL_SIZE);
label.setOpaque(true);
label.setLocation(random.nextInt(WIDTH - LBL_WIDTH),
random.nextInt(HEIGHT - LBL_HEIGHT));
label.setBackground(new Color(150 + random.nextInt(105),
150 + random.nextInt(105), 150 + random.nextInt(105)));
label.addMouseListener(myMouseAdapter);
label.addMouseMotionListener(myMouseAdapter);
mainPanel.add(label);
}
}
public JComponent getMainPanel() {
return mainPanel;
}
private class MyMouseAdapter extends MouseAdapter {
private Point initLabelLocation = null;
private Point initMouseLocationOnScreen = null;
#Override
public void mousePressed(MouseEvent e) {
JLabel label = (JLabel)e.getSource();
// get label's initial location relative to its container
initLabelLocation = label.getLocation();
// get Mouse's initial location relative to the screen
initMouseLocationOnScreen = e.getLocationOnScreen();
}
#Override
public void mouseReleased(MouseEvent e) {
initLabelLocation = null;
initMouseLocationOnScreen = null;
}
#Override
public void mouseDragged(MouseEvent e) {
// if not dragging a JLabel
if (initLabelLocation == null || initMouseLocationOnScreen == null) {
return;
}
JLabel label = (JLabel)e.getSource();
// get mouse's new location relative to the screen
Point mouseLocation = e.getLocationOnScreen();
// and see how this differs from the initial location.
int deltaX = mouseLocation.x - initMouseLocationOnScreen.x;
int deltaY = mouseLocation.y - initMouseLocationOnScreen.y;
// change label's position by the same difference, the "delta" vector
int labelX = initLabelLocation.x + deltaX;
int labelY = initLabelLocation.y + deltaY;
label.setLocation(labelX, labelY);
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createGui();
}
});
}
private static void createGui() {
JFrame frame = new JFrame("App");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new DragLabelEg().getMainPanel());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}

JApplet drawing shapes

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
#SuppressWarnings("serial")
public class ShapeApplet extends JApplet{
//contains all shapes that created
private ShapeContainer shapeContaiter = new ShapeContainer();
//main window panels
private Panel leftPanel = new Panel();
private Panel rightPanel = new Panel();
private Panel buttomPanel = new Panel();
//the panel inside right panel
private Panel shapesPanel = new Panel();
private String [] shapeNames = {"Cicle","Rect","Polygon","Line","Cylinder"};
private Choice shapeChoice = new Choice();
//defines the colors to choose from
JColorChooser colorChooser = new JColorChooser(Color.BLACK);
//item that will be use for painting
private Shape shapeToDraw;
//creating shapesButtons
ImageIcon iconCircle = new ImageIcon("circle.png", "Circle");
JButton buttonCircle = new JButton(iconCircle);
ImageIcon iconLine = new ImageIcon("line.png","Line");
JButton buttonLine = new JButton(iconLine);
ImageIcon iconRect = new ImageIcon("rect.png","Line");
JButton buttonRect = new JButton(iconRect);
ImageIcon iconPolygon = new ImageIcon("polygon.png","Line");
JButton buttonPolygon = new JButton(iconPolygon);
//creating the other tool buttons
JButton buttonClear = new JButton("Undo");
Checkbox checkBoxIsTheShapeFilled = new Checkbox("Filled");
//defines the new canvas
PaintingCanvas paintingCanvas = new PaintingCanvas();
//defines the class for buttons actions
ButtonAction buttonAction = new ButtonAction();
//save the shape that selected
private int currentTool = 4;
//integers to keep the mouse location
private int xPoint1, xPoint2 = 0, yPoint1,yPoint2 = 0;
#Override
public void init() {
System.out.println("points" + xPoint1+yPoint2);
//setting location , size and properties
Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
int screenWidth = (int) dim.getWidth();
int screenHeight = (int) dim.getHeight();
this.setSize(screenWidth,screenHeight-400);
//setting layout
this.setLayout(new BorderLayout());
//creating the choices for shapes
for(int i = 0 ; i < shapeNames.length ; i++ )
shapeChoice.add(shapeNames[i]);
//defines left Panel and right Panel properties
this.leftPanel.setBackground(Color.LIGHT_GRAY);
this.leftPanel.setLayout(new GridLayout(5, 0));
this.rightPanel.setBackground(Color.LIGHT_GRAY);
this.rightPanel.setLayout(new BorderLayout());
//adding items to the right panel
this.rightPanel.add(colorChooser, BorderLayout.NORTH);
//setting the shapes panel
this.shapesPanel.setLayout(new GridLayout(3,3));
this.shapesPanel.add(buttonCircle);
this.shapesPanel.add(buttonLine);
this.shapesPanel.add(buttonRect);
this.shapesPanel.add(buttonPolygon);
this.shapesPanel.add(checkBoxIsTheShapeFilled);
//adding the shapes panel to the right Panel
this.rightPanel.add(shapesPanel, BorderLayout.SOUTH);
//adding items to the left panel
this.leftPanel.add(buttonClear);
//defines the location of each item on the main window
this.add(leftPanel, BorderLayout.WEST);
this.add(rightPanel, BorderLayout.EAST);
this.add(buttomPanel,BorderLayout.SOUTH);
this.add(paintingCanvas,BorderLayout.CENTER);
//setting button actions
this.buttonCircle.addActionListener(buttonAction);
this.buttonLine.addActionListener(buttonAction);
this.buttonPolygon.addActionListener(buttonAction);
this.buttonRect.addActionListener(buttonAction);
this.buttonClear.addActionListener(buttonAction);
}
#Override
public void start() {
super.start();
}
#Override
public void stop() {
super.stop();
}
#Override
public void destroy() {
super.destroy();
}
public class PaintingCanvas extends Canvas implements MouseListener, MouseMotionListener
{
public PaintingCanvas()
{
addMouseListener(this);
}
#Override
public void mouseClicked(MouseEvent e) {
}
#Override
public void mouseEntered(MouseEvent e) {
}
#Override
public void mouseExited(MouseEvent e) {
}
#Override
public void mousePressed(MouseEvent e) {
xPoint1 = e.getX();
yPoint1 = e.getY();
xPoint2 = e.getX();
yPoint2 = e.getY();
}//end of mousePressed
#Override
public void mouseReleased(MouseEvent e) {
xPoint2 = e.getX();
yPoint2 = e.getY();
shapeContaiter.add(shapeToDraw);
System.out.println("Release");
repaint();
}
#Override
public void update(Graphics g) {
paint(g);
}//end of update
#Override
public void paint(Graphics g) {
switch (currentTool)
{
case 0:
//System.out.println("Circle pointsxy: " + xPoint1+","+yPoint1);
//System.out.println("Circle pointsx2y2: " + xPoint2+","+yPoint2);
shapeToDraw = new Circle(xPoint1 , yPoint1, new Point(xPoint2, yPoint2),colorChooser.getColor() , checkBoxIsTheShapeFilled.getState());
//System.out.println( "Circle pointsxy: " + shapeToDraw.getLocation());
shapeToDraw.draw(g);
break;
case 1:
shapeToDraw = new Line(xPoint1, yPoint1, new Point(xPoint2,yPoint2), colorChooser.getColor(), checkBoxIsTheShapeFilled.getState());
shapeToDraw.draw(g);
break;
case 2:
break;
case 3:
shapeToDraw = new Rect(xPoint1, yPoint1, new Point(xPoint2, yPoint2), colorChooser.getColor(), checkBoxIsTheShapeFilled.getState());
shapeToDraw.draw(g);
break;
case 4:
break;
default:
}//end of switch
System.out.println("Size of shapeContianer: "+shapeContaiter.size());
System.out.println("pointsxy: " + xPoint1+","+yPoint1);
System.out.println("pointsx2y2: " + xPoint2+","+yPoint2);
}//end of paint
#Override
public void mouseDragged(MouseEvent e) {
}
#Override
public void mouseMoved(MouseEvent e) {
// TODO Auto-generated method stub
}
}//end of canvas
public class ButtonAction implements ActionListener
{
#Override
public void actionPerformed(ActionEvent e) {
if ( e.getSource() == buttonCircle)
currentTool = 0;
else if ( e.getSource() == buttonLine)
currentTool = 1;
else if ( e.getSource() == buttonPolygon)
currentTool = 2;
else if ( e.getSource() == buttonRect)
currentTool = 3;
else if (e.getSource() == buttonClear){
currentTool=4;
if(shapeContaiter.isEmpty()) JOptionPane.showMessageDialog(buttonClear, "Nothing to delete");
else {
Graphics g = paintingCanvas.getGraphics();
shapeContaiter.get(shapeContaiter.size()-1).setColor(Color.WHITE);
shapeContaiter.get(shapeContaiter.size()-1).draw(g);
shapeContaiter.remove(shapeContaiter.size()-1);
System.out.println("Size of shapeContianer: "+shapeContaiter.size());
}
}
}//end of action performed
}//end of ButtonClicked
}
I'm trying to create an Undo button that will erase the last shape from the shapeContainer array and from the canvas.
i can put the finger on the problem but when i am trying to erase on of the shapes it erase the shape that i painted before the current shape.
i created Circle,Rect,Polygon,Line classes that after heavy checking seems to be ok.
What is the ShapeContainer class? Instead why don't you just use a Stack http://download.oracle.com/javase/6/docs/api/java/util/Stack.html
Why the use of awt Panel and Canvas? I would suggest just using JPanel and JComponents instead.
Your Button listener is looking very scary with all the if and else statements. Instead use a separate listener for each button. This will simplify the logic which in turn will prevent bugs in your code and make it easier to make changes. (The Action class in the API might be useful to you in this case).

Categories