1

i have screen with 4k resolution and 150% scaling on windows

Main class

`   
public static void main(String[] args) throws IOException {
 
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
       frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
        frame.setPreferredSize(new Dimension(displayMode.getWidth(), displayMode.getHeight()));
        frame.setUndecorated(true);
        frame.add(new Background());
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
}`

And Background

`public class Background extends JPanel implements ActionListener {
    public Background() throws IOException {
        backGround = ImageIO.read(getClass().getClassLoader().getResourceAsStream("background.jpg"));
      
        setBackground(Color.BLACK);
        addMouseListener(new MyMouseListener(this));
        addKeyListener(new MyKeyboardListener(this));
        setFocusable(true);
        requestFocusInWindow();
        setOpaque(true);
`

method paint in Background where iam trying to draw images in a few threads

`@Override
    protected void paintComponent(Graphics g) {
for (Map.Entry<String, Map<BaseShip, Integer>> player : playersShips.entrySet()) {

            Thread thread = new Thread(new Runnable() {
@Override
                public void run() {
                    DisplayMode displayMode = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDisplayMode();
                    BufferedImage bufferedImage = new BufferedImage( displayMode.getWidth(), displayMode.getHeight(), BufferedImage.TYPE_INT_ARGB);
                    Graphics graphics = bufferedImage.getGraphics();
                    Map<BaseShip, Integer> value = new HashMap<>(player.getValue());
                    Iterator<Map.Entry<BaseShip, Integer>> iterator = value.entrySet().iterator();
                    while (iterator.hasNext()) {
                        Map.Entry<BaseShip, Integer> entry = iterator.next();
                        BaseShip baseShip = entry.getKey();
                        if (!baseShip.isKilled()) {
                            baseShip.paint(graphics);
                        } else {
                            iterator.remove();
                        }
                    }

                    graphics.dispose();
                    bufferedImages.put(player.getKey(), bufferedImage);
                    player.setValue(value);
                }
            });
            threads.add(thread);
            thread.start();
        }
        for (Thread thread : threads) {
            try {
                thread.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        for (Map.Entry<String, BufferedImage> bufferedImage : bufferedImages.entrySet()) {
            g.drawImage(bufferedImage.getValue(), 0, 0, null);
        }
}`

the problem that JPanel method paint witch drawing another images, lines etc for bufferedImage draws with scaling in mind and does it in resolution 2600x1440, when bufferedImage has 3840x2160 from DisplayMode and what i can see at debug mode: enter image description here

after this image will stretched to the resolution of the monitor to 4k cos i am using frame.setExtendedState(JFrame.MAXIMIZED_BOTH);, but it lose quality

tried remove frame.setExtendedState(JFrame.MAXIMIZED_BOTH);, and after this nothing is displayed on the screen

tried add setSize(new Dimension(displayMode.getWidth(), displayMode.getHeight())); at Background and it isn't helps, the image is still low resolution

setSize() at Main at still low resolution and new problem where method paint is calling many times before main image on main thread shows at screen, this problem still staying if application working at 1 thread

get Graphics2D for bufferedImage, same.

and many combinations setSizes 4k for Main and Background

only if iam down screen scaling to 100% with JFrame.MAXIMIZED_BOTH all working good, but that's not the way, apllications must have to take into account screen scaling without down scaling images

or discard from multi-threaded image processing, then my app working slowly and thats why need multi-threading for this

  • 1
    1) You should NOT be using Threads to paint your images. Just iterate through the Map and paint each image. 2) Not sure I understand the question but maybe you can use the concept presented here: https://stackoverflow.com/a/65742492/131872. That is reset the AffineTransform of the Graphics object back to a scaling factor of 1 so no scaling is done. Post an [mre] demonstrating the problem. 3) Note, I'm not even sure how the painting loops work since you always appear to be painting the image at (0, 0), so each image would paint over top of one another? – camickr Jun 14 '23 at 20:35
  • Painting is for painting nothing else. Swing is not thread safe, so you shouldn’t be modifying the ui from outside the context of the event dispatching thread – MadProgrammer Jun 14 '23 at 23:09
  • Also consider providing a [mcve] – MadProgrammer Jun 14 '23 at 23:11
  • 2
    thx for camickr, https://stackoverflow.com/questions/65742162/how-to-fix-the-blurry-image-when-i-run-my-java-swing-project/65742492#65742492 solve my problem – Ярослав Jun 15 '23 at 06:26

0 Answers0