问题
I have a JInternalFrame that I draw on with Graphics2D. Each Graphics2D object is drawn in a location based on a java.util.List. I am interested in updating the location of the points on a componentResized event and then repaint the Graphics2D objects, in effect scaling with the window, but I cannot figure out how to do it. I tried overloading the componentResized to get the new window size and add to the points in the list but this isn't working.
EDIT: After some help (alright a lot of help) from Camickr I figured out how to solve this issue that has been most annoying for several days. Fixed code is below:
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import java.util.*;
import javax.swing.*;
public class ShapeTransform extends JPanel implements ComponentListener
{
private ArrayList<Shape> shapes = new ArrayList<Shape>();
private double scale = 1.0;
public ShapeTransform()
{
shapes.add(new Ellipse2D.Double(10, 10, 20, 20));
shapes.add( new Ellipse2D.Double(30, 30, 20, 20) );
shapes.add( new Ellipse2D.Double(50, 50, 20, 20) );
shapes.add( new Ellipse2D.Double(70, 70, 20, 20) );
addComponentListener(this);
addMouseListener( new MouseAdapter()
{
@Override
public void mousePressed(MouseEvent e)
{
Point p = new Point((int)(e.getX() / scale), (int)(e.getY() / scale));
for (Shape shape : shapes)
{
if (shape.contains(p))
{
System.out.println("shape pressed");
return;
}
}
System.out.println("no shape pressed");
}
});
}
@Override
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
Graphics2D g2d = (Graphics2D)g.create();
g2d.setColor( Color.BLUE );
AffineTransform tx = new AffineTransform(); //
tx.concatenate( g2d.getTransform() );
tx.scale(scale, scale);
g2d.setTransform(tx);
shapes.forEach(g2d::fill);
g2d.dispose();
}
private static void createAndShowGUI()
{
JFrame frame = new JFrame("ShapeTransform");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new ShapeTransform());
frame.setLocationByPlatform(true);
frame.setSize(400, 400);
frame.setVisible( true );
}
public static void main(String[] args)
{
EventQueue.invokeLater(() -> createAndShowGUI());
}
@Override
public void componentResized(ComponentEvent e) {
scale = ((1.0 - ((300 - getHeight()) * .0035)) + (1.0 - ((300 - getWidth()) * .0035)) / 2);
System.out.println(scale);
System.out.println(getHeight());
}
@Override
public void componentMoved(ComponentEvent e) {
}
@Override
public void componentShown(ComponentEvent e) {
}
@Override
public void componentHidden(ComponentEvent e) {
}
public void setScale(double scale)
{
this.scale = scale;
}
}
回答1:
One last answer, unless you start provide a proper SSCCE
with your question.
The code below is an example of a SSCCE. Only the code needed to demonstrate the problem (or solution) is posted.
If you can't simplify your code then it means you don't understand your question or your problem.
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import java.util.*;
import javax.swing.*;
public class ShapeTransform extends JPanel
{
private ArrayList<Shape> shapes = new ArrayList<Shape>();
private double scale = 1.0;
public ShapeTransform()
{
shapes.add( new Ellipse2D.Double(10, 10, 20, 20) );
shapes.add( new Ellipse2D.Double(30, 30, 20, 20) );
shapes.add( new Ellipse2D.Double(50, 50, 20, 20) );
shapes.add( new Ellipse2D.Double(70, 70, 20, 20) );
addMouseListener( new MouseAdapter()
{
@Override
public void mousePressed(MouseEvent e)
{
Point p = new Point((int)(e.getX() / scale), (int)(e.getY() / scale));
for (Shape shape: shapes)
{
if (shape.contains(p))
{
System.out.println("shape pressed");
return;
}
}
System.out.println("no shape pressed");
}
});
}
@Override
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
Graphics2D g2d = (Graphics2D)g.create();
g2d.setColor( Color.BLUE );
AffineTransform tx = new AffineTransform(); //
tx.concatenate( g2d.getTransform() );
tx.scale(scale, scale);
g2d.setTransform(tx);
for (Shape shape : shapes)
{
g2d.fill( shape );
}
g2d.dispose();
}
public void setScale(double scale)
{
this.scale = scale;
}
private static void createAndShowGUI()
{
JFrame frame = new JFrame("ShapeTransform");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new ShapeTransform());
frame.setLocationByPlatform( true );
frame.setSize(400, 400);
frame.setVisible( true );
}
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
createAndShowGUI();
}
});
}
}
I'll let you add the ComponentListener to the panel so you can dynamically change the scale.
If you can't solve the problem, then you have a proper SSCCE that you can update your question with.
Once you solve the problem and understand the concept, then you fix your real program.
来源:https://stackoverflow.com/questions/32291400/updating-a-listpoint-on-componentresized-event