I
Ian Stanley
Hi,
I am having trouble trying to revise a old java program(& understand
transforms). Code is below.
-- I have a ArrayList of shapes and need to rotate only the selected shape
My problem is how to rotate the selected shape without rotating all of the
shapes.
I realise that after rotating the selected shape it has to be added to the
ArrayList wtith its new orientation --
the same as moving a shape to update its location. But how?
Any help will be appreciated. I would then like to add more
features(scaling, adding text etc -for another time)
A cut down working version with what I need to achieve is below. The idea is
to draw a number of shapes, select the rotate button, then click on a shape
to rotate it 45degress. This "new shape" is saved so it can later be
selected for rotation/moving again.
Thanking you in advance
Ian.
import javax.swing.*;
import java.awt.*;
import java.awt.geom.*;
import java.awt.event.*; // Needed for ActionEvent and ActionListener
import java.util.*;
public class drawer extends JFrame
{
private static final int NONE = 0, RECT = 1, LINE = 2, MOVE = 3,
ROTATE = 4;
private ShapePanel drawPanel;
private JPanel buttonPanel;
private JButton drawRect, drawLine, rotate;
private TextField msg;
public drawer()
{
super("drawer");
drawPanel = new ShapePanel(400, 190);
buttonPanel = new JPanel();
buttonPanel.setLayout(new GridLayout (1, 1));
drawRect = new JButton("Draw Rect");
drawLine = new JButton("Draw Line");
rotate = new JButton("Rotate");
ButtonHandler bhandler = new ButtonHandler();
drawRect.addActionListener(bhandler);
drawLine.addActionListener(bhandler);
rotate.addActionListener(bhandler);
buttonPanel.add(drawRect);
buttonPanel.add(drawLine);
buttonPanel.add(rotate);
drawPanel.setMode(NONE);
msg = new TextField("");
msg.setEditable(false);
buttonPanel.add(msg);
Container c = getContentPane();
drawPanel.setBackground(Color.white);
c.add(drawPanel, BorderLayout.CENTER);
c.add(buttonPanel, BorderLayout.SOUTH);
setSize(900, 400);
show();
}
public static void main(String [] args)
{
drawer win = new drawer();
win.addWindowListener(
new WindowAdapter()
{
public void windowClosing(WindowEvent e)
{ System.exit(0); }
}
);
}
private class ButtonHandler implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
if (e.getSource() == drawRect)
{
drawPanel.setMode(RECT);
msg.setText("Use Mouse to Draw Rect");
}
else if (e.getSource() == drawLine)
{
drawPanel.setMode(LINE);
msg.setText("Use Mouse to Draw Line");
}
else if (e.getSource() == rotate)
{
drawPanel.setMode(ROTATE);
msg.setText("Click on Shape to Rotate 1/4 to Right)");
}
}
}
private class ShapePanel extends JPanel
{
private ArrayList shapeList; // In panel keep track of shapes
and
private ArrayList colorList; // colors
private Shape newShape;
private int prefwid, prefht;
private int selindex;
private int x1, y1, x2, y2; // used by mouse event handlers when
// drawing and moving the shapes
private int mode; // since reaction to mouse is different
if we are
// creating or moving a shape, we must keep
track
private boolean created;
public ShapePanel (int pwid, int pht)
{
shapeList = new ArrayList();
colorList = new ArrayList();
selindex = -1;
prefwid = pwid; // values used by getPreferredSize method
below
prefht = pht; // (which is called implicitly)
setOpaque(true);
addMouseListener( // anonymous inner class
new MouseAdapter() {
public void mousePressed(MouseEvent e)
{
x1 = e.getX(); // store where mouse is
when clicked
y1 = e.getY();
if (mode == drawer.RECT || mode ==
drawer.LINE)
// if drawing,
indicate that
created = false; // a new shape
is about to
// be drawn
else if (mode == drawer.ROTATE){
selindex = getSelected(x1, y1); //
find shape
if (selindex >= 0) //
mouse is
msg.setText("Rotate Shape"); //
pointing to
}
else if (mode == drawer.NONE)
{
selindex = getSelected(x1, y1); //
find shape
if (selindex >= 0) //
mouse is
msg.setText("Moving Shape"); //
pointing to
}
repaint();
}
public void mouseReleased(MouseEvent e)
{
mode = drawer.NONE;
if (selindex >= 0)
{
colorList.set(selindex,
Color.black);
selindex = -1; // actions end
when mouse is
repaint(); // released, so
set back
}
msg.setText("");
}
}
);
addMouseMotionListener( // another anonymous
inner class
new MouseMotionAdapter() {
public void mouseDragged(MouseEvent
e)
{
x2 = e.getX(); // store where
mouse is now
y2 = e.getY();
if (mode == drawer.RECT)
{
if (!created) // create Rect
if not already
{ // created
newShape = new
Rectangle2D.Double
(x1,y1,(x2-x1),(y2-y1));
addshape(newShape);
created = true;
}
else // adjust boundaries
of shape if created
((RectangularShape)
newShape).
setFrame(x1, y1, (x2-x1),
(y2-y1));
}
else if (mode == drawer.LINE) //
same idea as above
{ //
but for Line2D object
if (!created)
{
newShape = new
Line2D.Double(x1, y1, x2, y2);
addshape(newShape);
created = true;
}
else
((Line2D)
newShape).setLine(x1, y1, x2, y2);
}
else if (mode == drawer.ROTATE &&
selindex >= 0){
// ???
// ???
}
else if (mode == drawer.NONE &&
selindex >= 0)
{
// We know item selected must be a
Rectangle
RectangularShape r =
(RectangularShape)
shapeList.get(selindex);
int width = (int) r.getWidth();
int height = (int)
r.getHeight();
r.setFrame(x2, y2, width,
height);
}
repaint();
}
}
);
} // end of constructor
private int getSelected(double x, double y) // See if x,y pos
of mouse
{ // falls within any
shape
for (int i = 0; i < shapeList.size(); i++)
{
if ( ((Shape) shapeList.get(i)).contains(x, y))
{
colorList.set(i, Color.red);
return i;
}
}
return -1;
}
public void setMode(int newMode) // set Mode
{
mode = newMode;
}
private void addshape(Shape newshape) // Add shape and color to
ArrayLists
{
shapeList.add(newshape);
colorList.add(Color.black);
repaint();
}
public Dimension getPreferredSize()
{
return new Dimension(prefwid, prefht);
}
public void paintComponent (Graphics g) // Pass the graphics
object
// to the Panel so
it can
// draw its shapes
{
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
AffineTransform at = new AffineTransform();
for (int i = 0; i < shapeList.size(); i++)
{
// if (mode == drawer.ROTATE){ // must be wrong
// at.rotate(Math.toRadians(45));
// }
g2d.setColor((Color) colorList.get(i));
g2d.draw((Shape) shapeList.get(i));
}
}
} // end of ShapePanel
} // end of drawer
I am having trouble trying to revise a old java program(& understand
transforms). Code is below.
-- I have a ArrayList of shapes and need to rotate only the selected shape
My problem is how to rotate the selected shape without rotating all of the
shapes.
I realise that after rotating the selected shape it has to be added to the
ArrayList wtith its new orientation --
the same as moving a shape to update its location. But how?
Any help will be appreciated. I would then like to add more
features(scaling, adding text etc -for another time)
A cut down working version with what I need to achieve is below. The idea is
to draw a number of shapes, select the rotate button, then click on a shape
to rotate it 45degress. This "new shape" is saved so it can later be
selected for rotation/moving again.
Thanking you in advance
Ian.
import javax.swing.*;
import java.awt.*;
import java.awt.geom.*;
import java.awt.event.*; // Needed for ActionEvent and ActionListener
import java.util.*;
public class drawer extends JFrame
{
private static final int NONE = 0, RECT = 1, LINE = 2, MOVE = 3,
ROTATE = 4;
private ShapePanel drawPanel;
private JPanel buttonPanel;
private JButton drawRect, drawLine, rotate;
private TextField msg;
public drawer()
{
super("drawer");
drawPanel = new ShapePanel(400, 190);
buttonPanel = new JPanel();
buttonPanel.setLayout(new GridLayout (1, 1));
drawRect = new JButton("Draw Rect");
drawLine = new JButton("Draw Line");
rotate = new JButton("Rotate");
ButtonHandler bhandler = new ButtonHandler();
drawRect.addActionListener(bhandler);
drawLine.addActionListener(bhandler);
rotate.addActionListener(bhandler);
buttonPanel.add(drawRect);
buttonPanel.add(drawLine);
buttonPanel.add(rotate);
drawPanel.setMode(NONE);
msg = new TextField("");
msg.setEditable(false);
buttonPanel.add(msg);
Container c = getContentPane();
drawPanel.setBackground(Color.white);
c.add(drawPanel, BorderLayout.CENTER);
c.add(buttonPanel, BorderLayout.SOUTH);
setSize(900, 400);
show();
}
public static void main(String [] args)
{
drawer win = new drawer();
win.addWindowListener(
new WindowAdapter()
{
public void windowClosing(WindowEvent e)
{ System.exit(0); }
}
);
}
private class ButtonHandler implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
if (e.getSource() == drawRect)
{
drawPanel.setMode(RECT);
msg.setText("Use Mouse to Draw Rect");
}
else if (e.getSource() == drawLine)
{
drawPanel.setMode(LINE);
msg.setText("Use Mouse to Draw Line");
}
else if (e.getSource() == rotate)
{
drawPanel.setMode(ROTATE);
msg.setText("Click on Shape to Rotate 1/4 to Right)");
}
}
}
private class ShapePanel extends JPanel
{
private ArrayList shapeList; // In panel keep track of shapes
and
private ArrayList colorList; // colors
private Shape newShape;
private int prefwid, prefht;
private int selindex;
private int x1, y1, x2, y2; // used by mouse event handlers when
// drawing and moving the shapes
private int mode; // since reaction to mouse is different
if we are
// creating or moving a shape, we must keep
track
private boolean created;
public ShapePanel (int pwid, int pht)
{
shapeList = new ArrayList();
colorList = new ArrayList();
selindex = -1;
prefwid = pwid; // values used by getPreferredSize method
below
prefht = pht; // (which is called implicitly)
setOpaque(true);
addMouseListener( // anonymous inner class
new MouseAdapter() {
public void mousePressed(MouseEvent e)
{
x1 = e.getX(); // store where mouse is
when clicked
y1 = e.getY();
if (mode == drawer.RECT || mode ==
drawer.LINE)
// if drawing,
indicate that
created = false; // a new shape
is about to
// be drawn
else if (mode == drawer.ROTATE){
selindex = getSelected(x1, y1); //
find shape
if (selindex >= 0) //
mouse is
msg.setText("Rotate Shape"); //
pointing to
}
else if (mode == drawer.NONE)
{
selindex = getSelected(x1, y1); //
find shape
if (selindex >= 0) //
mouse is
msg.setText("Moving Shape"); //
pointing to
}
repaint();
}
public void mouseReleased(MouseEvent e)
{
mode = drawer.NONE;
if (selindex >= 0)
{
colorList.set(selindex,
Color.black);
selindex = -1; // actions end
when mouse is
repaint(); // released, so
set back
}
msg.setText("");
}
}
);
addMouseMotionListener( // another anonymous
inner class
new MouseMotionAdapter() {
public void mouseDragged(MouseEvent
e)
{
x2 = e.getX(); // store where
mouse is now
y2 = e.getY();
if (mode == drawer.RECT)
{
if (!created) // create Rect
if not already
{ // created
newShape = new
Rectangle2D.Double
(x1,y1,(x2-x1),(y2-y1));
addshape(newShape);
created = true;
}
else // adjust boundaries
of shape if created
((RectangularShape)
newShape).
setFrame(x1, y1, (x2-x1),
(y2-y1));
}
else if (mode == drawer.LINE) //
same idea as above
{ //
but for Line2D object
if (!created)
{
newShape = new
Line2D.Double(x1, y1, x2, y2);
addshape(newShape);
created = true;
}
else
((Line2D)
newShape).setLine(x1, y1, x2, y2);
}
else if (mode == drawer.ROTATE &&
selindex >= 0){
// ???
// ???
}
else if (mode == drawer.NONE &&
selindex >= 0)
{
// We know item selected must be a
Rectangle
RectangularShape r =
(RectangularShape)
shapeList.get(selindex);
int width = (int) r.getWidth();
int height = (int)
r.getHeight();
r.setFrame(x2, y2, width,
height);
}
repaint();
}
}
);
} // end of constructor
private int getSelected(double x, double y) // See if x,y pos
of mouse
{ // falls within any
shape
for (int i = 0; i < shapeList.size(); i++)
{
if ( ((Shape) shapeList.get(i)).contains(x, y))
{
colorList.set(i, Color.red);
return i;
}
}
return -1;
}
public void setMode(int newMode) // set Mode
{
mode = newMode;
}
private void addshape(Shape newshape) // Add shape and color to
ArrayLists
{
shapeList.add(newshape);
colorList.add(Color.black);
repaint();
}
public Dimension getPreferredSize()
{
return new Dimension(prefwid, prefht);
}
public void paintComponent (Graphics g) // Pass the graphics
object
// to the Panel so
it can
// draw its shapes
{
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
AffineTransform at = new AffineTransform();
for (int i = 0; i < shapeList.size(); i++)
{
// if (mode == drawer.ROTATE){ // must be wrong
// at.rotate(Math.toRadians(45));
// }
g2d.setColor((Color) colorList.get(i));
g2d.draw((Shape) shapeList.get(i));
}
}
} // end of ShapePanel
} // end of drawer