Screenshot ist verschoben.

Status
Nicht offen für weitere Antworten.

Tobias

Top Contributor
Hallo,

ich habe folgendes vor: Ich habe ein Programm, das diverse Formulare anzeigt. Wenn jetzt in diesem Programm ein länger dauernder, blockender Prozess gestartet wird, soll das zuletzt gezeigte Formular im Hintergrund sichtbar bleiben, darüber wird ein grau-transparenter Farbverlauf gelegt und darüber wiederum ein Panel mit dem JProgressBar und einigen Labels, die weitere Infos zu dem Prozess liefern. Sozusagen ein schönerer modaler Dialog, dem einen oder anderen vielleicht von Picasa bekannt.

Um das technisch umsetzen zu können, habe ich vor, einen Screenshot des jeweils letzten Formulars zu nehmen, um dieses im Hintergrund anzeigen zu können. Leider kriege ich es nicht hin, den Screenshot genau auf den entsprechenden JComponent auszurichten, es fehlt oben und links jeweils ein Pixel (Was zu Pixelsprüngen des "Hintergrundes" aka Formulars führt und so bestimmt nicht durch die Testabteilung kommt ...).

Hier der Code, den ich zur Anpassung des Bildschirmbereichs benutze (target ist der abzulichtende JComponent):

Code:
                Rectangle r = target.getBounds();
		Point newLoc = (Point) r.getLocation().clone();
		SwingUtilities.convertPointToScreen(newLoc, target);
		r.setLocation(newLoc);
		BufferedImage screen = new Robot().createScreenCapture(r);

Die clone() / setLocation()-Konstruktion habe ich gewählt, weil Rectangle anscheinend eine Kopie des benutzten Points rausgibt (Direkte Änderungen an der gelieferten Referenz bringen jedenfalls nichts). Das clone() macht diesen Umstand nur deutlicher.

Für alle, die das Problem live erleben wollen:

Code:
public class ScreenshotTest extends JFrame implements ActionListener {
	
	private JPanel left = createLeftPanel();
	
	private JPanel right = new JPanel();
	
	public ScreenshotTest() {
		super("ScreenshotTest");
		setLayout(new BorderLayout());
		setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
		setExtendedState(JFrame.MAXIMIZED_BOTH);
		
		JSplitPane split = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
		split.setDividerLocation(Toolkit.getDefaultToolkit().getScreenSize().width / 2);
		split.add(left);
		split.add(right);
		
		add(split, BorderLayout.CENTER);
		add(createButtonBar(), BorderLayout.SOUTH);
		setVisible(true);
	}
	
	public Box createButtonBar() {
		Box b = new Box(BoxLayout.LINE_AXIS);
		
		JButton butt = new JButton("Screenshot!");
		butt.addActionListener(this);
		b.add(butt);
		b.add(Box.createGlue());
		
		return b;
	}
	
	public JPanel createLeftPanel() {
		JPanel p = new JPanel();
		p.setLayout(new BoxLayout(p, BoxLayout.PAGE_AXIS));
		p.setBorder(BorderFactory.createMatteBorder(1, 1, 1, 1, Color.RED));
		
		p.add(new JLabel("Toller Text!"));
		p.add(new JTextField(25) {
			@Override
			public Dimension getMaximumSize() {
				return getPreferredSize();
			}
		});
		p.add(Box.createRigidArea(new Dimension(10, 10)));
		p.add(new JLabel("Hallo Tobias!"));
		p.add(Box.createGlue());
		
		return p;
	}
	
	public JXPanel createScreenshotPanel(JComponent target) throws AWTException {
		JXPanel screenShot = new JXPanel();
		Rectangle r = target.getBounds();
		Point newLoc = (Point) r.getLocation().clone();
		SwingUtilities.convertPointToScreen(newLoc, target);
		r.setLocation(newLoc);
		BufferedImage screen = new Robot().createScreenCapture(r);
		
		ImagePainter paint = new ImagePainter(screen);
		Color transGray = new Color(Color.GRAY.getRed() / 255f, Color.GRAY.getGreen() / 255f, Color.GRAY.getBlue() / 255f, 0.7f);
		Color transLightGray = new Color(Color.LIGHT_GRAY.getRed() / 255f, Color.LIGHT_GRAY.getGreen() / 255f, Color.LIGHT_GRAY.getBlue() / 255f, 0.7f);
		GradientPaint gPaint = new GradientPaint(
				0f, 0f,
			    transLightGray,
			    1f, 1f,
			    transGray);
		BasicGradientPainter bgPaint = new BasicGradientPainter(gPaint);
//		PinstripePainter psPaint = new PinstripePainter(transLightGray, 45);
//		psPaint.setSpacing(16);
//		psPaint.setStripeWidth(1.0);
		screenShot.setBackgroundPainter(new CompoundPainter(paint, bgPaint/*, psPaint*/));
		
		screenShot.setSize(target.getSize());
		
		screenShot.setLayout(null);
		JLabel label = new JLabel("Hallo!");
		label.setLocation(screenShot.getSize().width / 2, screenShot.getSize().height / 2);
		label.setSize(new Dimension(100, 100));
		label.setOpaque(true);
		screenShot.add(label);
		
		return screenShot;
	}

	/**
	 * @param args
	 * @throws AWTException 
	 */
	public static void main(String[] args) {
		new ScreenshotTest();
	}

	/*
	 * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
	 */
	public void actionPerformed(ActionEvent e) {
		try {
			right.removeAll();
			right.add(createScreenshotPanel(left));
			repaint();
		}
		catch(Exception ex) {
		}
	}

}

Das Anzeigen des Screenshots ist ziemlich hakelig. Mehrfaches Drücken des Buttons "Screenshot" hilft. Verschieben des SplitPane-Dividers ist tödlich für dieses Testprogramm (im Sinne von "Angezeigter Screenshot verschwindet dann").

mpG
Tobias

EDIT. Oben und links fehlt je ein Pixel, nicht "oben und rechts".
 

Marco13

Top Contributor
Mangels BasicGradientPainter, JXPanel & Co kann ich es zwar nicht testen, aber ... soweit ich weiß gehört die Border nicht zur component. Wenn du also für das "left" Panel eine Border setzt, und dann nur für's "left" panel den Screenshot anfertigst, kann es sein, dass die Border dann fehlt... Ist aber nur ein Tipp... :?
 

Tobias

Top Contributor
Wenn ich die Border allerdings statt auf 1 Pixel auf 5 Pixel setze und es dann test, fehlt trotzdem nur ein ixel, die Border wird also anscheinend mit eingerechnet. Ich habe jetzt den berechneten Point vorerst um einen Pixel nach oben links korrigiert und damit den Fehler behoben. Warum dieser Effekt überhaupt auftritt, interessiert mich trotzdem.

mpG
Tobias
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
L JavaFX JavaFX Screenshot Machen AWT, Swing, JavaFX & SWT 6
F Screenshot eines JPanel AWT, Swing, JavaFX & SWT 3
F AWT Robot Klasse Screenshot nach Pixelmustern in bestimmten Radius um Bildschirmmittelpunkt absuchen AWT, Swing, JavaFX & SWT 13
K Screenshot AWT, Swing, JavaFX & SWT 6
A AWT Beim (mehrmaligen) Screenshot machen läuft der Speicher voll AWT, Swing, JavaFX & SWT 2
0 2D-Grafik Screenshot von ScrollBar-Inhalt AWT, Swing, JavaFX & SWT 2
N screenshot machen ohne Robots? AWT, Swing, JavaFX & SWT 9
F Screenshot vom Desktop machen? AWT, Swing, JavaFX & SWT 2
C JList: Eintrag anklicken & JTextfield mit Text aus MySQL füllen? (Screenshot dabei) AWT, Swing, JavaFX & SWT 8
G GUI Screenshot AWT, Swing, JavaFX & SWT 5
D Robot: Screenshot vom Desktop Hintergrund möglich ? AWT, Swing, JavaFX & SWT 3
H Screenshot abhängig von Grafikkarte? AWT, Swing, JavaFX & SWT 15
T Screenshot mit SWT AWT, Swing, JavaFX & SWT 5
A Screenshot eines best. Fensters AWT, Swing, JavaFX & SWT 5
R Screenshot von fremder Anwendung AWT, Swing, JavaFX & SWT 4
H Was ist das für eine Komponente ? (Screenshot) AWT, Swing, JavaFX & SWT 8
A Screenshot einer Anwendung erstellen AWT, Swing, JavaFX & SWT 14
M Bildschirnkoordinaten und Screenshot? AWT, Swing, JavaFX & SWT 2
R JPanel als Screenshot in eine Datei schreiben AWT, Swing, JavaFX & SWT 3
D Zoom problem!!! (brauche screenshot...) plz help thx AWT, Swing, JavaFX & SWT 7
Z Swing Swing: Elemente werden doppel/verschoben gezeichnet, sind teils unsichtbar etc... AWT, Swing, JavaFX & SWT 10
V JTabbedPane Eingefügte Labels verschoben AWT, Swing, JavaFX & SWT 2
M rotate Text wird verschoben angezeigt? AWT, Swing, JavaFX & SWT 23
S Swing Während Frame verschoben wird... AWT, Swing, JavaFX & SWT 2
S Swing Text -> HTML: Caret-Koordinaten verschoben AWT, Swing, JavaFX & SWT 6
G JTable warten bis Spalte verschoben wurde AWT, Swing, JavaFX & SWT 2
S GUI wird verschoben AWT, Swing, JavaFX & SWT 6

Ähnliche Java Themen

Neue Themen


Oben