Jdesktoppane background without losing quality and expandable

Asked

Viewed 1,677 times

5

I have code to add a background image to a JDesktopPaneand it works perfectly on widescreen 16:10 screens. However, when the screen is a little wider (16:9), it does not fill the rest of the background. I’ve seen some other possible ways to do it, but they make the picture lose a lot of quality, because they just stretch it out.

Is it possible to make a middle ground ? something that fills when necessary, and that there is not so significant loss in the image?

package novo;

import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import javax.swing.ImageIcon;
import javax.swing.JDesktopPane;
import javax.swing.JFrame;
import javax.swing.JOptionPane;

public class TesteJDP extends JFrame {

    private static MeuJDesktopPane jdp = new MeuJDesktopPane();

    public TesteJDP() {
        getContentPane().add(jdp);
        setSize(500, 450);
        setLocationRelativeTo(null);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
    }

    public static void main(String[] args) {
        TesteJDP teste = new TesteJDP();
        teste.setVisible(true);
    }
}

class MeuJDesktopPane extends JDesktopPane {

    private Image imagem;

    public MeuJDesktopPane() {
        try {
            imagem = new ImageIcon(getClass().getResource("/imagens/fundo.png")).getImage();
        } catch (Exception e) {
            JOptionPane.showMessageDialog(null, "Não foi possivel ler a imagem !");

        }
    }

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        Dimension dimension = this.getSize();
        int x = (int) (dimension.getWidth() - imagem.getWidth(this)) / 2;
        int y = (int) (dimension.getHeight() - imagem.getHeight(this)) / 2;
        g.drawImage(imagem, x, y, imagem.getWidth(this), imagem.getHeight(this), this);
    }
}
  • The middle term you already answered, fix the window size as the image or put a larger image.

  • @diegofm has tried to put a very large image, I do not know what happens, it does not fill everything. There’s no way to add some dimension or something to fill in ?

  • What are the dimensions of the image?

  • @diegofm 2.362 px X 1.570 px

  • Your window is only (500, 450) in size, as a 3x larger image does not fill everything?

1 answer

4


Note: The solution was applied to a JDesktopPane, but as the method paintComponent(Graphics g) is of origin of the class JComponent, is inherited by all components of the swing API (except some components top-level containers), this solution will probably work for any component of the API.


Based in this answer on Soen, the image can be scaled according to the area shown on the screen, using BufferedImage.

First it is necessary to create an instance of BufferedImage with the dimensions you want the image to be scaled:

//dimensoes do componente do qual a imagem servirá de background
Dimension dimension = this.getSize();
int dWidth = (int)dimension.getWidth();
int dHeight = (int)dimension.getHeight();

bi = new BufferedImage(dWidth, dHeight, BufferedImage.TYPE_INT_RGB);

After creating an instance, we need to draw the image with the dimensions informed and optionally set some settings to improve the quality. The code has the proper explanations about what each line does:

//cria uma instância de gráficos a partir do BufferedImage
Graphics2D g2 = bi.createGraphics();
//define algumas configurações de interpolação, renderização e antialiasing
//para melhorar um pouco a qualidade da imagem quando for dimensionada
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g2.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
//renderiza a imagem dentro do BufferedImage
g2.drawImage(imagem, 0, 0, dWidth, dHeight, null);
//com a imagem já desenhada, dispensa essa instância de gráficos
g2.dispose();
//desenha a imagem já dimensionada no componente
g.drawImage(bi, 0, 0, null);

Now just add in the method paintComponent of the component, not forgetting to check if the image is valid before trying to draw it on the screen:

@Override
public void paintComponent(Graphics g) {
    super.paintComponent(g);

    BufferedImage bi;

    if (imagem != null) {

        Dimension dimension = this.getSize();
        int dWidth = (int)dimension.getWidth();
        int dHeight = (int)dimension.getHeight();

        bi = new BufferedImage(dWidth, dHeight, BufferedImage.TYPE_INT_RGB);
        //cria uma versao 2D de graficos para que possamos desenhar a imagem na tela
        Graphics2D g2 = bi.createGraphics();
        //define algumas configurações de interpolação, renderização e antialiasing
        //para melhorar um pouco a qualidade da imagem quando for dimensionada
        g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
        g2.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        //desenha a imagem dentro do BufferedImagem
        g2.drawImage(imagem, 0, 0, dWidth, dHeight, null);
        g2.dispose();
        //finalmente, desenha a imagem já dimensionada no componente
        g.drawImage(bi, 0, 0, null);

    }
}

See the result with a 2560x1600 image resized to 300x250:

inserir a descrição da imagem aqui

Example code can be found this github link.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.