我是AffineTransform的新手,但是我花了几个小时的时间,想出了如何让它做我想做的事情。基本上我的目标是制作一个JInternal Frame,在最小化时缩放Graphics2D对象。为了概念验证,我创建了一些使用鼠标滚轮缩放的代码,并在鼠标拖动时进行转换。
我的问题是,如何将其打包到JInternalFrame中,该JInternalFrame在最小化JInternalFrame时进行缩放?还有,有更好的方法来做我想做的事吗?
自包含的例子:
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.AffineTransform;
import java.awt.geom.Ellipse2D;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import javax.swing.JComponent;
import javax.swing.JFrame;
public class AffineTransformTest {
private static TransformingCanvas canvas;
public static void main(String[] args) {
TransformingCanvas.initializePointList();
JFrame frame = new JFrame();
canvas = new TransformingCanvas(TransformingCanvas.POINT_LIST);
TranslateHandler translator = new TranslateHandler();
canvas.addMouseListener(translator);
canvas.addMouseMotionListener(translator);
canvas.addMouseWheelListener(new ScaleHandler());
frame.setLayout(new BorderLayout());
frame.getContentPane().add(canvas, BorderLayout.CENTER);
frame.setSize(750, 750);
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.setVisible(true);
}
private static class TransformingCanvas extends JComponent {
private double translateX;
private double translateY;
private double scale;
private final int PREF_W = 800; //Window width
private final int PREF_H = 800; //Window height
private static final Color INACTIVE_COLOR = Color.RED;
private static final Color ACTIVE_COLOR = Color.green;
private java.util.List<Point> points;
private java.util.List<Ellipse2D> ellipses = new ArrayList<>();
private Map<Ellipse2D, Color> ellipseColorMap = new HashMap<>();
public static java.util.List<Point> POINT_LIST = new ArrayList<>();
/*
* This loop will initialize POINT_LIST with the set of points for drawing the ellipses.
* The for each loop initializes points for the top row and the second for loop draws the
* right triangle.
*/
protected static void initializePointList() {
int ellipsePointsYCoordinate[] = {140, 200, 260, 320, 380, 440, 500, 560, 620};
int ellipsePointsXCoordinate[] = {140, 200, 260, 320, 380, 440, 500, 560, 620, 680};
int xx = 80;
for (int aXt : ellipsePointsXCoordinate) {
POINT_LIST.add(new Point(aXt, xx));
}
for (int i = 0; i < ellipsePointsYCoordinate.length; i++) {
for (int j = i; j < ellipsePointsYCoordinate.length; j++) {
POINT_LIST.add(new Point(ellipsePointsXCoordinate[i], ellipsePointsYCoordinate[j]));
}
}
}
TransformingCanvas() {
translateX = 0;
translateY = 0;
scale = 1;
setOpaque(true);
setDoubleBuffered(true);
}
public TransformingCanvas(java.util.List<Point> points) {
this.points = points;
int OVAL_WIDTH = 30;
for (Point p : points) {
int x = p.x - OVAL_WIDTH / 2;
int y = p.y - OVAL_WIDTH / 2;
int w = OVAL_WIDTH;
int h = OVAL_WIDTH;
Ellipse2D ellipse = new Ellipse2D.Double(x, y, w, h);
ellipses.add(ellipse);
ellipseColorMap.put(ellipse, INACTIVE_COLOR);
}
}
@Override public void paint(Graphics g) {
AffineTransform tx = new AffineTransform();
tx.translate(translateX, translateY);
tx.scale(scale, scale);
Graphics2D g2 = (Graphics2D) g;
g2.fillRect(0,0, getWidth(), getHeight());
g2.setTransform(tx);
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
for (Ellipse2D ellipse : ellipses) {
g2.setColor(ellipseColorMap.get(ellipse));
g2.fill(ellipse);
g2.setColor(Color.BLACK);
g2.setStroke(new BasicStroke(2));
g2.draw(ellipse);
}
/*
* Set the font characteristics, color, and draw the row labels.
*/
g.setFont(new Font("TimesRoman", Font.BOLD, 18));
g.setColor(Color.BLACK);
//NOTE to self: add label DrawStrings back
//Draws a 3DRect around the top row of ellipse2D objects
g2.setColor(Color.lightGray);
g2.draw3DRect(120, 60, 580, 40, true);
g2.draw3DRect(121, 61, 578, 38, true);
g2.draw3DRect(122, 62, 576, 36, true);
//super.paint(g);
}
}
private static class TranslateHandler implements MouseListener,
MouseMotionListener {
private int lastOffsetX;
private int lastOffsetY;
public void mousePressed(MouseEvent e) {
// capture starting point
lastOffsetX = e.getX();
lastOffsetY = e.getY();
}
public void mouseDragged(MouseEvent e) {
// new x and y are defined by current mouse location subtracted
// by previously processed mouse location
int newX = e.getX() - lastOffsetX;
int newY = e.getY() - lastOffsetY;
// increment last offset to last processed by drag event.
lastOffsetX += newX;
lastOffsetY += newY;
// update the canvas locations
canvas.translateX += newX;
canvas.translateY += newY;
// schedule a repaint.
canvas.repaint();
}
public void mouseClicked(MouseEvent e) {}
public void mouseEntered(MouseEvent e) {}
public void mouseExited(MouseEvent e) {}
public void mouseMoved(MouseEvent e) {}
public void mouseReleased(MouseEvent e) {}
}
private static class ScaleHandler implements MouseWheelListener {
public void mouseWheelMoved(MouseWheelEvent e) {
if(e.getScrollType() == MouseWheelEvent.WHEEL_UNIT_SCROLL) {
// make it a reasonable amount of zoom
// .1 gives a nice slow transition
canvas.scale += (.1 * e.getWheelRotation());
// don't cross negative threshold.
// also, setting scale to 0 has bad effects
canvas.scale = Math.max(0.00001, canvas.scale);
canvas.repaint();
}
}
}
}
答案 0 :(得分:2)
我不完全明白为什么你会想要在Graphics
不可见的情况下进行缩放,但这里有一个粗略的指示:
JDesktopPane
设置为JFrame
的contentpane。JInternalFrame
并添加JDesktopPane
InternalFrameListener
,然后如果内部框架最小化,您可以将public void internalFrameIconified(InternalFrameEvent arg0)
方法放在内部。这是在您的代码中实现的(没有任何AffineTransform
,只是基本概念):
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.AffineTransform;
import java.awt.geom.Ellipse2D;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import javax.swing.JComponent;
import javax.swing.JDesktopPane;
import javax.swing.JFrame;
import javax.swing.JInternalFrame;
import javax.swing.event.InternalFrameEvent;
import javax.swing.event.InternalFrameListener;
public class AffineTransformTest {
private static TransformingCanvas canvas;
public static void main(String[] args) {
TransformingCanvas.initializePointList();
JFrame frame = new JFrame();
canvas = new TransformingCanvas(TransformingCanvas.POINT_LIST);
JDesktopPane desktop = new JDesktopPane();
TranslateHandler translator = new TranslateHandler();
canvas.addMouseListener(translator);
canvas.addMouseMotionListener(translator);
canvas.addMouseWheelListener(new ScaleHandler());
MyInternalFrame iFrame = new MyInternalFrame();
iFrame.setLayout(new BorderLayout());
iFrame.add(canvas, BorderLayout.CENTER);
iFrame.setVisible(true);
desktop.add(iFrame);
frame.setContentPane(desktop);
frame.setSize(750, 750);
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.setVisible(true);
}
private static class TransformingCanvas extends JComponent {
private double translateX;
private double translateY;
private double scale;
private final int PREF_W = 800; // Window width
private final int PREF_H = 800; // Window height
private static final Color INACTIVE_COLOR = Color.RED;
private static final Color ACTIVE_COLOR = Color.green;
private java.util.List<Point> points;
private java.util.List<Ellipse2D> ellipses = new ArrayList<>();
private Map<Ellipse2D, Color> ellipseColorMap = new HashMap<>();
public static java.util.List<Point> POINT_LIST = new ArrayList<>();
/*
* This loop will initialize POINT_LIST with the set of points for
* drawing the ellipses. The for each loop initializes points for the
* top row and the second for loop draws the right triangle.
*/
protected static void initializePointList() {
int ellipsePointsYCoordinate[] = { 140, 200, 260, 320, 380, 440,
500, 560, 620 };
int ellipsePointsXCoordinate[] = { 140, 200, 260, 320, 380, 440,
500, 560, 620, 680 };
int xx = 80;
for (int aXt : ellipsePointsXCoordinate) {
POINT_LIST.add(new Point(aXt, xx));
}
for (int i = 0; i < ellipsePointsYCoordinate.length; i++) {
for (int j = i; j < ellipsePointsYCoordinate.length; j++) {
POINT_LIST.add(new Point(ellipsePointsXCoordinate[i],
ellipsePointsYCoordinate[j]));
}
}
}
TransformingCanvas() {
translateX = 0;
translateY = 0;
scale = 1;
setOpaque(true);
setDoubleBuffered(true);
}
public TransformingCanvas(java.util.List<Point> points) {
this.points = points;
int OVAL_WIDTH = 30;
for (Point p : points) {
int x = p.x - OVAL_WIDTH / 2;
int y = p.y - OVAL_WIDTH / 2;
int w = OVAL_WIDTH;
int h = OVAL_WIDTH;
Ellipse2D ellipse = new Ellipse2D.Double(x, y, w, h);
ellipses.add(ellipse);
ellipseColorMap.put(ellipse, INACTIVE_COLOR);
}
}
@Override
public void paint(Graphics g) {
AffineTransform tx = new AffineTransform();
tx.translate(translateX, translateY);
tx.scale(scale, scale);
Graphics2D g2 = (Graphics2D) g;
g2.fillRect(0, 0, getWidth(), getHeight());
g2.setTransform(tx);
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
for (Ellipse2D ellipse : ellipses) {
g2.setColor(ellipseColorMap.get(ellipse));
g2.fill(ellipse);
g2.setColor(Color.BLACK);
g2.setStroke(new BasicStroke(2));
g2.draw(ellipse);
}
/*
* Set the font characteristics, color, and draw the row labels.
*/
g.setFont(new Font("TimesRoman", Font.BOLD, 18));
g.setColor(Color.BLACK);
// NOTE to self: add label DrawStrings back
// Draws a 3DRect around the top row of ellipse2D objects
g2.setColor(Color.lightGray);
g2.draw3DRect(120, 60, 580, 40, true);
g2.draw3DRect(121, 61, 578, 38, true);
g2.draw3DRect(122, 62, 576, 36, true);
// super.paint(g);
}
}
private static class TranslateHandler implements MouseListener,
MouseMotionListener {
private int lastOffsetX;
private int lastOffsetY;
public void mousePressed(MouseEvent e) {
// capture starting point
lastOffsetX = e.getX();
lastOffsetY = e.getY();
}
public void mouseDragged(MouseEvent e) {
// new x and y are defined by current mouse location subtracted
// by previously processed mouse location
int newX = e.getX() - lastOffsetX;
int newY = e.getY() - lastOffsetY;
// increment last offset to last processed by drag event.
lastOffsetX += newX;
lastOffsetY += newY;
// update the canvas locations
canvas.translateX += newX;
canvas.translateY += newY;
// schedule a repaint.
canvas.repaint();
}
public void mouseClicked(MouseEvent e) {
}
public void mouseEntered(MouseEvent e) {
}
public void mouseExited(MouseEvent e) {
}
public void mouseMoved(MouseEvent e) {
}
public void mouseReleased(MouseEvent e) {
}
}
private static class ScaleHandler implements MouseWheelListener {
public void mouseWheelMoved(MouseWheelEvent e) {
}
}
static class MyInternalFrame extends JInternalFrame implements
InternalFrameListener {
public MyInternalFrame() {
super("iFrame", true, // resizable
true, // closable
true, // maximizable
true);// iconifiable
setSize(300, 300);
addInternalFrameListener(this);
}
@Override
public void internalFrameActivated(InternalFrameEvent arg0) {
}
@Override
public void internalFrameClosed(InternalFrameEvent arg0) {
}
@Override
public void internalFrameClosing(InternalFrameEvent arg0) {
}
@Override
public void internalFrameDeactivated(InternalFrameEvent arg0) {
}
@Override
public void internalFrameDeiconified(InternalFrameEvent arg0) {
}
@Override
public void internalFrameIconified(InternalFrameEvent arg0) {
System.out.println("Minimized");
//What you want to do
}
@Override
public void internalFrameOpened(InternalFrameEvent arg0) {
}
}
}
如果现在你仍然无法达到你想要的效果,请进一步解释,因为我没有真正看到缩放图形不可见的重点。
现在,我了解真正的问题是:您可以向ComponentListener
添加JInternalFrame
。然后在public void componentResized(ComponentEvent e) {
方法中放入您想要更改的所有内容(可能是Graphics
的宽度和高度的变量)。使用上面的代码,只需将MyInternalFrame
类更改为:
static class MyInternalFrame extends JInternalFrame implements
ComponentListener {
public MyInternalFrame() {
super("iFrame", true, // resizable
true, // closable
true, // maximizable
true);// iconifiable
setSize(300, 300);
addComponentListener(this);
}
@Override
public void componentHidden(ComponentEvent e) {
}
@Override
public void componentMoved(ComponentEvent e) {
}
@Override
public void componentResized(ComponentEvent e) {
System.out.println("Resized");
System.out.println("Width: " + getWidth());
System.out.println("Height: " + getHeight());
System.out.println();
}
@Override
public void componentShown(ComponentEvent e) {
}
}
我会告诉您如何调整大小(将componentResized
方法更改为此内容):
@Override
public void componentResized(ComponentEvent e) {
String str = "";
if (getWidth() < 1000) {
str = "0." + getWidth();
} else {
str = "1." + (getWidth()-1000);
System.out.println(getWidth()-1000);
}
double dou = Double.parseDouble(str);
canvas.scale = dou;
}