Größe der BufferStrategy in der Window-Klasse

PissPain

Aktives Mitglied
Hallo, meine Window-Klasse sieht zurzeit so aus:
Java:
package window;

import java.awt.Canvas;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.image.BufferStrategy;
import java.lang.reflect.InvocationTargetException;

import javax.swing.JFrame;
import javax.swing.SwingUtilities;

public class Window extends Canvas implements Runnable {

	/**
	 * 
	 */
	private static final long serialVersionUID = -7150710923108249953L;
	private BufferStrategy bufferStrategy;
	private JFrame frame;
	
	public Window(int width, int height, String title) {
		setPreferredSize(new Dimension(width, height));
		
		frame = new JFrame(title);
		frame.add(this);
		frame.pack();
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setLocationRelativeTo(null);
		frame.setResizable(false);
	}

	@Override
	public void run() {
		try {
			SwingUtilities.invokeAndWait(new Runnable() {

				@Override
				public void run() {
					createBufferStrategy(2);
					bufferStrategy = getBufferStrategy();
					frame.setVisible(true);
					setFocusable(true);
					requestFocus();
				}
				
			});
			
			while(true) {
				Graphics g = bufferStrategy.getDrawGraphics();
				g.setColor(Color.blue);
				g.fillRect(0, 0, getWidth(), getHeight());
				g.dispose();
				bufferStrategy.show();
				
				Thread.sleep(16);
			}
		} catch (InvocationTargetException | InterruptedException e) {}
	}
}

Wie kann ich es schaffen, der BufferStrategy eine exakte Größe zu geben?
Wenn ich meiner Window-Klasse also der Canvas die Größe 600x600 zuweise, dann habe ich eine Zeichenfläche von 610x610. Einfach 590x590 zuweisen, würde sich dann trotzdem auf anderen Computern ändern, da die andere Layouts benutzen könnten. Oder hat das einen anderen Grund?
Naja, hoffe, dass ihr mir da ne schönere Lösung geben könnt.

Vielen Dank 🙂
 
Zuletzt bearbeitet:
Der Code ist ja eine Katastrophe. Ich hab jetzt mal ein paar Fragen an dich:

1. Was willst du überhaupt tun?
2. Weißt du überhaupt was eine BufferStrategy ist und was sie macht?
3. Warum verwendest du awt?
 
Ich will auf einer Fläche zeichnen können, dessen Größe von mir festgelegt wird. Die Größe soll unabhängig von dem Design des Computers sein.

Die BufferStrategy sollte dafür sorgen, auf den Wiederaufbau des Bildes auf dem Monitor zu warten, sodass das Bild nicht ineinander gezeichnet wird. Das ist auch der Grund, weshalb ich einen neuen Thread starte, da, falls ich etwas updaten wollen würde, die update-Geschwindigkeit dieselbe wie die draw-Geschwindigkeit wäre und das alle bewegende Objekte zum zittern bringen würde.

Falls du mit awt Canvas meinst, dann liegt es daran, dass ich mit der BufferStrategy nicht in das Design des Fensters zeichnen möchte. Also, Canvas hilft mir dabei, auf die richtige Fläche zu zeichnen, wodurch aber das Problem mit der Größe zustande kommt. Und von einem JCanvas habe ich nicht gehört^^

Vielen Dank 🙂
 
Zuletzt bearbeitet:
Nein aber du könntest mit Swing arbeiten. Swing arbeitet meines Wissens nach standardmäßig mit DoubleBuffering. Also das Einzige was du tun musst, ist von JComponent (resp. JPanel) ableiten.

Hier ein kleines Beispiel:

Java:
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class Test {

  public static void main(String... args) {
    SwingUtilities.invokeLater(Test::new);
  }

  public Test() {
    JFrame frame = new JFrame("Canvas");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setLocationByPlatform(true);
    JPanel mainPanel = new JPanel();
    mainPanel.add(new MyCanvas(600, 400));
    frame.add(mainPanel);
    frame.pack();
    frame.setVisible(true);
  }

  private class MyCanvas extends JComponent {

    private final Dimension preferredDimension;
    private List<Point> points;

    public MyCanvas(int width, int height) {
      preferredDimension = new Dimension(width, height);
      points = new ArrayList<>();
      addMouseListener(new MouseAdapter() {

        @Override
        public void mousePressed(MouseEvent e) {
          if (SwingUtilities.isLeftMouseButton(e)) {
            points.add(e.getPoint());
            repaint();
          }
        }

        @Override
        public void mouseReleased(MouseEvent e) {
          if (SwingUtilities.isLeftMouseButton(e)) {
            points.add(e.getPoint());
            repaint();
          }
        }
      });
      addMouseMotionListener(new MouseMotionAdapter() {

        @Override
        public void mouseDragged(MouseEvent e) {
          points.add(e.getPoint());
          System.out.println(e.getPoint());
          repaint();
        }
      });
    }

    @Override
    public Dimension getPreferredSize() {
      return preferredDimension;
    }

    @Override
    protected void paintComponent(Graphics g) {
      super.paintComponent(g);
      g.drawPolyline(points.stream().mapToInt(p -> p.x).toArray(), points.stream().mapToInt(p -> p.y).toArray(), points.size());
      g.drawString(String.valueOf(points.size()), getWidth() >> 1, getHeight() >> 1);
    }
  }
}
PS: Ist mit Java 8 geschrieben.
 
Ich habe es so abgeändert, dass es mir passt. Die Zeichenfläche ist auch so, wie ich es wollte, danke.
Eins noch, mit Zeichenfläche meinte nicht wirklich "Zeichnen", sondern eine Fläche, auf der ich mit einem Graphics Object machen kann, was ich will. So hat es aber auch geklappt, nochmals danke 🙂
 

Neue Themen


Zurück
Oben