There are bascially two different approaches for this:
- You can "scale the whole
Graphics
"
- You can scale the actual shapes
The difference may be subtle in some cases, but can be important: When you scale the whole Graphics
, then everything will be scaled. Particularly, when you scale it about 2.0
, and then draw a line with a width of 1.0
, the line will be drawn 2 pixels wide. Whether or not this is desired depends on the application case.
In order to scale the actual shapes, you can not use the drawRect
method. Instead you will have to create Shape
instances that represent the geometric shapes. You can then create scaled versions of these shapes with AffineTransform#createTransformedShape
.
Here is an example that compares both approaches (and corrects some of the other issues that have been in your code). In both cases, the same rectangle with an original size of (10,13) is painted, scaled by a factor of 5.0.
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Shape;
import java.awt.geom.AffineTransform;
import java.awt.geom.Rectangle2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class ScalingDrawnObjects
{
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable()
{
@Override
public void run()
{
createAndShowGUI();
}
});
}
private static void createAndShowGUI()
{
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
ScalingDrawnObjectsPanel p = new ScalingDrawnObjectsPanel();
f.getContentPane().add(p);
f.setSize(600,400);
f.setLocationRelativeTo(null);
f.setVisible(true);
}
}
class ScalingDrawnObjectsPanel extends JPanel
{
@Override
protected void paintComponent(Graphics gr)
{
super.paintComponent(gr);
Graphics2D g = (Graphics2D)gr;
Shape rectangle = new Rectangle2D.Double(2, 2, 10, 13);
g.setColor(Color.RED);
drawWithScaledGraphics(g, rectangle);
g.translate(100, 0);
drawScaledObject(g, rectangle);
}
private static void drawWithScaledGraphics(Graphics2D g, Shape shape)
{
AffineTransform oldAt = g.getTransform();
g.scale(5.0, 5.0);
g.draw(shape);
g.setTransform(oldAt);
}
private static void drawScaledObject(Graphics2D g, Shape shape)
{
AffineTransform at = AffineTransform.getScaleInstance(5.0, 5.0);
g.draw(at.createTransformedShape(shape));
}
}
EDIT In response to the comment
The code that I posted is not "complicated". It is as compilcated as it has to be, but not more. You should not extend JFrame
and you should not override paint
. You should create the GUI on the EDT. You should ...
However, you should not use code like the following, but maybe this is what you're looking for
import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JFrame;
import java.awt.Dimension;
public class Stretch extends JFrame {
int originalHeight = 600;
int originalWidth = 600;
public Stretch() {
super("Stretch");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(originalWidth, originalHeight);
}
public static void main(String[] args) {
Stretch s = new Stretch();
s.setVisible(true);
}
public void paint(Graphics g) {
Dimension size = this.getBounds().getSize();
int rectWidth = 100;
int rectHeight = 130;
g.setColor(Color.white);
g.fillRect(0, 0, size.width, size.height);
g.setColor(Color.black);
int w = rectWidth + size.width - originalWidth;
int h = rectHeight + size.height - originalHeight;
double sx = (double)w / rectWidth;
double sy = (double)h / rectHeight;
double s = Math.min(sx, sy);
int fw = (int)(s * rectWidth);
int fh = (int)(s * rectHeight);
g.drawRect(100, 100, fw, fh);
}
}