0

I am creating a wrapper for Notch's "Prelude of the Chambered", and I wish to make it so that you can resize the window. I can not figure out how I could make the contents scale, I have tried to override onPaint. I can not modify the Jar to get this done.

onPaint attempt:

package com.gudenau.pc.poc;

import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.image.BufferedImage;

import javax.swing.JFrame;

public class JScaledFrame extends JFrame {

    private static final long serialVersionUID = 4044340683411982494L;

    public JScaledFrame(String title) {
        super(title);
    }

    @Override
    public void paint(Graphics graphics){
        Dimension min = getMinimumSize();
        Dimension size = getSize();

        BufferedImage image = new BufferedImage(min.width, min.height, BufferedImage.TYPE_4BYTE_ABGR);
        Graphics subGraphics = image.getGraphics();
        super.paint(subGraphics);
        subGraphics.dispose();

        graphics.drawImage(image, 0, 0, size.width, size.height, null);
    }
}
gudenau
  • 500
  • 5
  • 19
  • Why are you trying to implement a double buffering strategy in Swing? Swing components are already double buffered...with the exception of top level containers, but you really should not be overriding paint without good reason – MadProgrammer Aug 07 '14 at 00:35
  • I need to scale the image from the Applet. – gudenau Aug 07 '14 at 00:39
  • Then this is really going to be a good approach, you scaling the "view", but that won't scale how events are processed by it. Have a look at [this example](http://stackoverflow.com/questions/21439341/zooming-jlayeredpane-via-jlayer-and-the-layerui/21445118#21445118) and [this example](http://stackoverflow.com/questions/21174997/how-to-add-mouselistener-to-item-on-java-swing-canvas/21175125#21175125) which allow you to scale components but also scale the events that they need to operate...bewarned thought, I believe it will only work with Swing – MadProgrammer Aug 07 '14 at 00:42
  • If you are using an AWT based applet, you might find that's not possible, as AWT components are typically rendered at a native level...not saying it's not possible, but there is a lot to take into consideration... – MadProgrammer Aug 07 '14 at 00:42
  • All input is from a keyboard, so scaling is not a problem. – gudenau Aug 07 '14 at 00:44
  • Having now looked at the code, the problem is, the `EscapeComponent` is using a `BufferStrategy` which means nothing you do will ever have an effect as the `Canvas` is been updated outside of the normal painting process. The width and height values are hardcoded as is the scale, so you'd need to change this class directly. – MadProgrammer Aug 07 '14 at 02:18

3 Answers3

1

Do not paint on top level container such as JFrame. Use JComponent or JPanel. Override paintComponent() for painting rather than paint() and don't forget to call super.paintComponent(g).

Do painting in paintComponent nothing else. Avoid putting extra program logic or unnecessary allocations into that method. Painting operations should be fast and optimized for better performance and user experience.

Also, avoid null image observers when calling drawImage. JPanel for instance implements ImageObserver, so you can pass this if extending JPanel.

See Performing Custom Painting for more information. Also see Painting in AWT and Swing.

tenorsax
  • 21,123
  • 9
  • 60
  • 107
  • How would this scale an Applet though? That is what I need to do. – gudenau Aug 07 '14 at 00:37
  • @gudenau I misinterpreted your question. I am not sure you can scale the native component. However, the source for the game is available. You can change `EscapeComponent.SCALE = 4` to something else to achieve another size. – tenorsax Aug 07 '14 at 01:53
1

Scaling the content is very difficult. What you want to is change the scaling context of the Graphics context painting the underlying component.

Typically, what you would do, is override the paint method of the offending component and apply the scaling factor you want...

public class MyExtendedClass extends ... {
    @Override
    public void paint(Graphics g) {
        Graphics2D g2d = (Graphics2D)g.create();
        double scaleFactor = 1d;
        // Calculate the scaling factor to apply
        // based on the "default" size and the
        // current size...
        g2d.scale(scaleFactor, scaleFactor);
        super.paint(g2d);
        g2d.dispose();
    }
}

This could introduce all kinds of weirdness and frankly a more robust solution might be to use JXLayer/JLayer, for example...

You may also find using an AffineTransform easier...

Community
  • 1
  • 1
MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
0

Since it seems as though this will be hard to do with normal Java I will implement some dark magic with the ASM libraries. I was hoping it would not need to be done this way, but it seems as though scaling a canvas that is loaded from an external jar is not possible.

gudenau
  • 500
  • 5
  • 19