【发布时间】:2020-05-02 15:02:01
【问题描述】:
我是 Java 新手,我正在玩一个简单的 GUI 示例。在收到对我的last question 的良好答复后,我尝试更进一步,并根据帧大小(固定纵横比)缩放形状。事实上,当我改变窗口大小时,形状会随之缩放。但是,形状永远不会最大程度地填充框架,右侧和底部边缘总是有相当多的空间。代码如下:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.AffineTransform;
import java.awt.geom.Rectangle2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.WindowConstants;
public class DrawTest2 {
class DrawingPanel extends JPanel {
private Rectangle2D shape;
private JFrame frame;
public DrawingPanel(Rectangle2D shape, JFrame frame) {
this.shape = shape;
this.frame = frame;
}
public void paintComponent(Graphics g) {
Graphics2D g2D = (Graphics2D) g;
double scaleFactor = calcScaleFactor();
AffineTransform oldAt = g2D.getTransform();
AffineTransform tx1 = new AffineTransform();
tx1.scale(scaleFactor, scaleFactor);
super.paintComponent(g2D);
g2D.setTransform(tx1);
g2D.transform(AffineTransform.getTranslateInstance(3, 3));
g2D.setColor(new Color(31, 21, 1));
g2D.fill(shape);
g2D.draw(shape);
g2D.setTransform(oldAt);
}
@Override
public Dimension getPreferredSize() {
Dimension dimension = new Dimension((int)shape.getWidth(), (int)shape.getHeight());
System.out.println("Dimension: " + dimension); // 2000 x 500
return dimension;
}
private double calcScaleFactor() {
double maxX = shape.getMaxX();
double maxY = shape.getMaxY();
double widthPanel = frame.getContentPane().getSize().getWidth();
double heightPanel = frame.getContentPane().getSize().getHeight();
double minFactor;
if (widthPanel < maxX || heightPanel < maxY) {
double factorX = widthPanel/maxX;
double factorY = heightPanel/maxY;
minFactor = factorX < factorY ? factorX : factorY;
} else {
minFactor = 1.0;
}
System.out.println("widthPanel: " + widthPanel); // 1283
System.out.println("heightPanel: " + heightPanel); // 500
System.out.println("widthFrame: " + frame.getSize().getWidth()); // 1297
System.out.println("heightFrame: " + frame.getSize().getHeight()); // 537
System.out.println("maxX: " + maxX); // 2000
System.out.println("maxY: " + maxY); // 500
System.out.println("minFactor:" + minFactor); // 0.6415
return minFactor;
}
}
public void draw() {
JFrame frame = new JFrame();
Rectangle2D shape = new Rectangle2D.Float();
shape.setRect(0, 0, 2000, 500);
final DrawingPanel drawing = new DrawingPanel(shape, frame);
frame.getContentPane().add(drawing, BorderLayout.CENTER);
frame.pack();
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
public class DrawMain {
public static void main(String[] args) {
DrawTest2 test = new DrawTest2();
test.draw();
}
}
比例因子似乎没问题 (2000 * 0.6415 = 1283)。我的猜测是,虽然计算本身是正确的,但我在错误的地方应用了比例因子。对此的任何帮助将不胜感激。
编辑:这是我让问题更清楚的窗口截图:
EDIT2:这是更新后的代码(稍微重命名):
import java.awt.*;
import java.awt.geom.*;
import javax.swing.*;
public class DrawTest2 {
class DrawingPanel extends JPanel {
private Rectangle2D shape;
public DrawingPanel(Rectangle2D shape) {
this.shape = shape;
}
public void paintComponent(Graphics g) {
Graphics2D g2D = (Graphics2D) g;
double scaleFactor = calcScaleFactor();
AffineTransform oldAt = g2D.getTransform();
AffineTransform tx1 = new AffineTransform();
tx1.scale(scaleFactor, scaleFactor);
super.paintComponent(g2D);
g2D.setTransform(tx1);
g2D.setColor(new Color(31, 21, 1));
g2D.fill(shape);
g2D.draw(shape);
g2D.setTransform(oldAt);
}
@Override
public Dimension getPreferredSize() {
Dimension dimension = new Dimension((int)shape.getWidth(), (int)shape.getHeight());
return dimension;
}
private double calcScaleFactor() {
double maxX = shape.getMaxX();
double maxY = shape.getMaxY();
double widthPanel = getWidth();
double heightPanel = getHeight();
double minFactor;
double factorX = widthPanel/maxX;
double factorY = heightPanel/maxY;
minFactor = factorX < factorY ? factorX : factorY;
return minFactor;
}
}
public void draw() {
JFrame frame = new JFrame();
Rectangle2D shape = new Rectangle2D.Float();
shape.setRect(0, 0, 800, 500);
final DrawingPanel drawing = new DrawingPanel(shape);
frame.getContentPane().add(drawing, BorderLayout.CENTER);
frame.pack();
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setVisible(true);
}
public static void main(String[] args) {
DrawTest2 test = new DrawTest2();
test.draw();
}
}
这是shape.setRect(0, 0, 2000, 500) 的结果:
这是shape.setRect(0, 0, 800, 500) 的结果:
如果我将return minFactor 替换为return 1.0(并保留shape.setRect(0, 0, 2000, 500)),我会得到以下结果:
如果我将return minFactor 替换为return 0.9(并保留shape.setRect(0, 0, 2000, 500)),我会得到以下结果:
如果我将return minFactor 替换为return 0.9 并更改为shape.setRect(0, 0, 3000, 500),我会得到与return 1.0 和shape.setRect(0, 0, 2000, 500) 相同的可见结果。
【问题讨论】: