MousePosition über mehrere JPanels darstellen

Status
Nicht offen für weitere Antworten.

redbomber

Bekanntes Mitglied
Hi zusammen,
stellt euch vor ihr habt mehrere JPanels untereinander.
Wenn ich mit der Maus über einem der Panels bin, möchte ich einen senkrechten Strich an dieser Stelle über alle JPanels haben.

Meine Lösung -->
fange mouseMoved() Event von jedem Plot ab, setze für jedes JPanel die Position der Maus (Point) und rufe für jedes JPanel repaint(); auf.

Klappt auch alles, nur ist dieser senkrechte strich natürlich nicht ganz synchron, also wenn ich den über die Panels bewege, dann hängt der Strich bei manchen Panels etwas hinterher. sobald ich die Maus nicht mehr bewege passt aber alles.

Nun meine Frage:
Ist es möglich diesen Strich, welchen ich in der
Code:
public void paintComponent (Graphics g)
{
        super.paintComponent(g);
	final Graphics2D g2help = (Graphics2D) g;
	g2help.drawLine(mouseModel.getMousePointX(), 0, mouseModel.getMousePointX(), this.getHeight());
}

zeichne, irgendwie zu synchronisieren?
 

hdi

Top Contributor
edit: viel blabla um nix ;)

Dein Problem ist: Zuviel Zeichenaufwand, da kommt der EDT nicht hinterher.
Schau dir die Methode repaint(Rectangle) an!

edit2: Bedenke auch: Du musst nicht unbedingt bei JEDER mausbewegung repainten. Das menschliche Auge sieht eh nicht, ob sich das jede ms repaintet, oder jede 50 ms. Also bau dir nen counter/ticker ein, der nur repaintet wenn jedes zehnte mousemoved Event reingekommen ist oder eine gewisse Zeit ohne Event verstrichen ist.
 
Zuletzt bearbeitet:

hdi

Top Contributor
So, ich hab dir mal was gemacht. Ist per copy & paste lauffähig. Das kann man sicherlich noch an der ein oder anderen Stelle besser ausdesignen, aber es erfüllt seinen Zweck. (Und zwar "lazy" dirty region repaint, bzw. Repaint nach einem Timelimit)

Die einzelnen farbigen Streifen im Programm sind jeweils eigene JPanels.

[HIGHLIGHT="Java"]
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class Demo extends JFrame {

public static void main(String... x) {
new Demo("Fast Repaint").setVisible(true);
}

public Demo(String title) {
super(title);

PanelRepainter repainter = new PanelRepainter();

JPanel all = new JPanel();
all.setLayout(new BoxLayout(all, BoxLayout.Y_AXIS));
for (int i = 0; i < 30; i++) {
all.add(new BspPanel(repainter));
}

this.add(all);
pack();
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
}
}

class BspPanel extends JPanel implements LineDrawable, MouseMotionListener {

private static final Random r = new Random();

private int lineX;
private PanelRepainter repainter;

public BspPanel(PanelRepainter repainter) {
setPreferredSize(new Dimension(500, 20));
setBackground(new Color(r.nextInt(200), r.nextInt(200), r.nextInt(200)));
this.repainter = repainter;
repainter.register(this);

this.addMouseMotionListener(this);
}

@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.red);
g.drawLine(lineX, 0, lineX, getHeight());
}

@Override
public void setLineX(int lineX) {
this.lineX = lineX;
}

@Override
public void mouseDragged(MouseEvent arg0) {
}

@Override
public void mouseMoved(MouseEvent e) {
repainter.fireMouseMoved(this, e);
}

}

class PanelRepainter {

/* Limit nach wievielen MouseMove Events repaintet werden soll */
private static final int EVENT_LIMIT = 10;
/*
* Limit nach wievielen ms spätestens repainted werden soll, falls kein
* MouseEvent mehr eingetreten ist
*/
private static final long TIME_LIMIT = 100;

private List<JPanel> panels;
private int ticker;
private long lastFired;
private int latestLineX;
private JPanel latestUsed;
private boolean updated;

public PanelRepainter() {
panels = new ArrayList<JPanel>();
this.beginSpectating();
}

public void register(JPanel p) {
panels.add(p);
}

public void beginSpectating() {
new Thread() {
@Override
public void run() {
while (true) {
if (!updated && latestUsed != null) {
/*
* wir müssen uns "mit Gewalt" selber den aktuellen Wert
* aus dem Panel ziehen, weil wir ja kein Event bekommen
*/
Point pos = latestUsed.getMousePosition();
if (pos != null) {
doRepaints(pos.x);
updated = true;
}
}
try {
Thread.sleep(TIME_LIMIT);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}.start();
}

public void fireMouseMoved(JPanel src, MouseEvent e) {
if (++ticker == EVENT_LIMIT) {
doRepaints(e.getPoint().x);
ticker = 0;
}
latestUsed = src;
updated = false;
}

private void doRepaints(int newX) {
for (JPanel p : panels) {
((LineDrawable) p).setLineX(newX);
/* dirty region repaint: lösche alte Linie */
p.repaint(new Rectangle(latestLineX, 0, 1, p.getHeight()));
/* und zeichne neue: */
p.repaint(new Rectangle(newX, 0, 1, p.getHeight()));
}
lastFired = System.currentTimeMillis();
latestLineX = newX;
}
}

interface LineDrawable {
public void setLineX(int lineX);
}

[/HIGHLIGHT]
 
Zuletzt bearbeitet:

Ebenius

Top Contributor
Gegenvorschlag: JLayeredPane.
  1. 1 JLayeredPane mit OverlayLayout benutzen.
  2. Ein JPanel mit allen Deinen PlotPanels auf das JLayeredPane draufpappen
  3. Eine JComponent-Ableitung (siehe unten) auf das JLayeredPane draufpappen
  4. Freuen, weil man eine schönere Lösung hat :)

[HIGHLIGHT="Java"]class MouseTrackingPane extends JComponent {

private int mouX = -1;
private int mouY = -1;

/** Creates a new {@code MouseTrackingPane}. */
public MouseTrackingPane() {
enableEvents(AWTEvent.MOUSE_EVENT_MASK);
enableEvents(AWTEvent.MOUSE_MOTION_EVENT_MASK);
setForeground(Color.RED);
}

@Override
protected void processMouseEvent(MouseEvent e) {
super.processMouseEvent(e);
updateMouseCoords(e);
}

@Override
protected void processMouseMotionEvent(MouseEvent e) {
super.processMouseMotionEvent(e);
updateMouseCoords(e);
}

private void updateMouseCoords(MouseEvent e) {
final int x = e.getX();
final int y = e.getY();
if (x != mouX || y != mouY) {
mouX = x;
mouY = y;
repaint();
}
}

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

if (isOpaque()) {
g.setColor(getBackground());
g.fillRect(0, 0, getWidth(), getHeight());
}

final Insets ins = getInsets();
final int left = ins.left;
final int top = ins.top;
final int right = getWidth() - left - ins.right;
final int bottom = getHeight() - top - ins.bottom;
g.setColor(getForeground());
g.drawLine(left, mouY, right, mouY);
g.drawLine(mouX, top, mouX, bottom);
}
}[/HIGHLIGHT]
Ebenius
 

redbomber

Bekanntes Mitglied
ui :)

vielen Dank euch beiden, also war mein ansatz mal wieder ziemlich...ineffizient ;)
Ich probier das morgen gleich einmal aus und melde mich bestimmt wieder.
 

redbomber

Bekanntes Mitglied
sorry aber mit dem overlaylayout komme ich nicht klar:

Java:
public class MainLayeredPane extends JLayeredPane{

	protected Model model = null;
	protected MouseModel mouseModel = null;
	
	protected MouseTrackingPane mtp = null;

	public MainLayeredPane(Model model, MouseModel mouseModel){
		this.model = model;
		this.mouseModel = mouseModel;
                // HIERMIT SETZE ICH DAS OVERLAY LAYOUT FÜR MEINE JLAYEREDPANE
		OverlayLayout overlay = new OverlayLayout(this);
		this.setLayout(overlay);
	}
	
	/**
	 * add all plots to the JPanel.
	 * @param plotManager
	 * @param model
	 * @param mainPanel
	 * @param preferredHeight
	 * @param widthOfPlots
	 * @return
	 */
	public void addAllPlots() {

        // panel ist mein Panel, welches ich auf meine JLayeredPane draufpappe

		JPanel panel = new JPanel();
		panel.setLayout(new GridLayout(0,1));
		
		for (PlotData plotData : model.getListOfAllPlotDatas()) {
			
			MyPlot plot = new MyPlot(plotData, mouseModel, model);
			plot.setMinMaxValues();
			plotData.setPlotOfDataPlot(plot);
			panel.add(plot);
			model.addPlotToPlotlist(plot);
		}
	
// Hier pappe ich zuerst das Panel (welches wiederum viele Panels enthält) und dann das MouseTrackingPanel auf // meine JLayeredPane	

		this.add(panel);
	
		mtp = new MouseTrackingPane();
		this.add(mtp);
	}
}


Aber das ganze funktioniert nicht. Woran sehe ich wo sich das MouseTrackingPanel befindet?
Ist dieses unsichtbar im vordergrund?
Im Java tutorial wurde wie hier beschrieben vorgegangen: setze OverlayLayout für JLayeredPane, dann füge Panels hinzu und das wars...!?
 
Zuletzt bearbeitet von einem Moderator:

Ebenius

Top Contributor
Warum das bei Deinem Beispiel nicht geht, weiß ich nicht. Hier ist mein Test-Quelltext:
Java:
int rows = 5;
int cols = 5;
final JPanel panel = new JPanel();
panel.setLayout(new GridLayout(rows, cols));

for (int i = 0; i < cols; i++) {
  for (int j = 0; j < rows; j++) {
    final JPanel comp = new JPanel(new FlowLayout());
    final int val =
          ((j % 2) == 0 ? 1 : 2) * ((i % 2) == 0 ? 1 : 2) * 64 - 1;
    final Color bg = new Color(val, val, val);
    comp.setBackground(bg);
    comp.setForeground(Color.BLACK);
    comp.setOpaque(true);
    comp.setPreferredSize(new Dimension(70, 70));
    panel.add(comp);
  }
}

final JLayeredPane layeredPane = new JLayeredPane();
layeredPane.setLayout(new OverlayLayout(layeredPane));
layeredPane.add(panel, new Integer(1));
layeredPane.add(new MouseTrackingPane(), new Integer(2));

final JFrame f = new JFrame("Mouse Tracking");
f.getContentPane().add(layeredPane);
f.pack();
f.setLocationRelativeTo(null);
f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
f.setVisible(true);
Ebenius
 

redbomber

Bekanntes Mitglied
also jetzt gehts!

Vielen Dank!
Es hat nur bei dem
add(panel) der index gefehlt,

also add(panel, new Integer(1));
 

mvitz

Top Contributor
Und wieso nicht einfach?

Java:
add(panel, 1);

??? Neben Object kann man dort auch einfach int verwenden.
 

Ebenius

Top Contributor
Und wieso nicht einfach?

Java:
add(panel, 1);

??? Neben Object kann man dort auch einfach int verwenden.
Das sind unterschiedliche Dinge. Das Object identifiziert ein Layout Constraint. Das int nur die Komponenten-Reihenfolge und das Layout Constraint ist null. Siehe java.awt.Container:
Java:
public Component add(Component comp, int index) {
    addImpl(comp, null, index);
    return comp;
}

Ebenius
 

redbomber

Bekanntes Mitglied
Ich habe hier noch eine Frage zu einem Problem auf das ich gestoßen bin:

Ich habe bei mir folgende Struktur:

-> JDialog (Hauptfenster)
--> JScrollPane
--> JLayeredPane -> OverlayLayout
--> JPanel
--> Ein oder mehere Panels (stellen einen Plot von Daten dar)

Für kleine Daten (bis etwa 30000 Datenpunkte) klappt alles wunderbar. Für größere Datenmengen (bei mir sind es 11Mio) kommt es zu folgendem Problem:

Die JLayeredPane, sowie das JPanel, welches die PlotPanels enthält, werden zu klein dargestellt. Bzw. es wird nicht einmal etwas gezeichnet, sehe nur das weiße Panel.
Größe habe ich von allen Komponenten gesetzt (immer setSize() und setPreferredSize()) trotzdem diese Problem.

So, daraufhin habe ich das OVERLAYLAYOUT der JLayeredPane entfernt und einfach ein NULL Layout gewählt. Dann funktioniert alles. Aber ich brauche dieses Layout ja, da ich die Maus Position über alle Panels anzeigen möchte.


Nun meine Frage, woran kann das liegen daß die Darstellung für große Datenmengen nicht mehr funktioniert? Wieso gehts aber bei kleinen?
Wieso funktioniert alles wenn ich das OverlayLayout NICHT verwende?
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
D Zoom zur Mouseposition in ScrollPane AWT, Swing, JavaFX & SWT 5
E Swing JTable MousePosition nicht lesbar?! AWT, Swing, JavaFX & SWT 4
L Swing MousePosition in einem JPanel abfragen AWT, Swing, JavaFX & SWT 4
G MousePosition innerhalb eines MouseWheelEvents AWT, Swing, JavaFX & SWT 2
S MousePosition AWT, Swing, JavaFX & SWT 3
I JTextfield senden über Enter AWT, Swing, JavaFX & SWT 1
T Scene wechseln über ManuItem AWT, Swing, JavaFX & SWT 7
I JavaFX - Pane wechseln über 2. Controller AWT, Swing, JavaFX & SWT 5
melaniemueller Layout wechseln über RadioButtons AWT, Swing, JavaFX & SWT 4
melaniemueller Verschiebung eines Fensters über Button AWT, Swing, JavaFX & SWT 27
A Swing ProgressBar über 2 parallel laufende Threads AWT, Swing, JavaFX & SWT 2
A Layoutwechsel über RadioButtons AWT, Swing, JavaFX & SWT 3
CptK windowClosed() nur aufrufen, wenn Fenster nicht über Button geschlossen wird AWT, Swing, JavaFX & SWT 1
missy72 JavaFX Performance / ImageView in TableView über TimeLine AWT, Swing, JavaFX & SWT 1
T TableView über Methode befüllen AWT, Swing, JavaFX & SWT 10
J Spielfelder auch über die Tastatureingabe (1…9) ansteuern (Tic Tac Toe) AWT, Swing, JavaFX & SWT 2
M Eine Datei auf den Apache Server hochladen - über das Menü im JavaProgramm AWT, Swing, JavaFX & SWT 7
C Swing Aufruf der Funktion (die ein Dialog anzeigt) über Symbol anzeigen lassen AWT, Swing, JavaFX & SWT 4
G LayoutManager Panels anordnen über Schleifenvariablen AWT, Swing, JavaFX & SWT 7
F Verzeichnis über GUI erstellen AWT, Swing, JavaFX & SWT 2
T GUI über Tastatur bedienen AWT, Swing, JavaFX & SWT 3
OSchriever Layout über Radiobuttons ändern AWT, Swing, JavaFX & SWT 4
L JavaFX TreeView Edit Mode über F2 AWT, Swing, JavaFX & SWT 13
J Schriftart über einen Button ändern AWT, Swing, JavaFX & SWT 1
CptK Swing DropdownMenu über Panel-Grenzen hinaus anzeigen AWT, Swing, JavaFX & SWT 1
A 2D-Grafik Zeichen werden über unabhängingen JRadioButton nicht gefüllt AWT, Swing, JavaFX & SWT 28
S JavaFX Fenster aufkommen lassen, wenn mit der Maus über bestimmten Bereich fahren AWT, Swing, JavaFX & SWT 1
I Bild über FXML (ImageView, Image) anzeigen AWT, Swing, JavaFX & SWT 1
xYurisha JLabel Text einer geöffneten Gui über eine andere Klasse ändern! AWT, Swing, JavaFX & SWT 3
S Swing Rechteck über JTable zeichnen (per MouseListener) AWT, Swing, JavaFX & SWT 1
C JavaFX ScrollPane schießt über das Ziel hinaus... AWT, Swing, JavaFX & SWT 1
stroggi Swing Mehrere transparentes Objekte (Grafiken) über einem Bild (JLabel) darstellen AWT, Swing, JavaFX & SWT 4
R Ausgabe über JOptionPane.showMessageDialog funktioniert nicht AWT, Swing, JavaFX & SWT 2
L JavaFX button über andere Klasse ändern AWT, Swing, JavaFX & SWT 7
K über Button andere Java Klasse aufrufen AWT, Swing, JavaFX & SWT 15
T .jar-Datei lässt sich unflexibler ausführen als über die IDE AWT, Swing, JavaFX & SWT 11
C Applet Zeichnen über Button-Click AWT, Swing, JavaFX & SWT 13
L JavaFX Hover Effekt über das Parent Element AWT, Swing, JavaFX & SWT 4
C JavaFX GUI - Entscheidung über Framework AWT, Swing, JavaFX & SWT 4
A Swing Gemaltes Bild über saveDialog speichern unter AWT, Swing, JavaFX & SWT 15
L Dynamischer Aufbau einer Tabelle über Objekte AWT, Swing, JavaFX & SWT 2
N JButton über benutzerdefinierte paintComponent setzen AWT, Swing, JavaFX & SWT 3
S AWT Daten über TextField und Button in array speichern AWT, Swing, JavaFX & SWT 5
T Klasse über JButton schließen AWT, Swing, JavaFX & SWT 4
Augenblau JavaFX Externe Schriftart über CSS ansprechen und zuweisen AWT, Swing, JavaFX & SWT 5
T Generische Klasse in JList über DefaultListModel AWT, Swing, JavaFX & SWT 1
Z JAVAFX Stage über Controller weitergeben um css-file zu laden AWT, Swing, JavaFX & SWT 4
Z Absolutes Layout / Kontrolle über Anordnung AWT, Swing, JavaFX & SWT 3
wolfgang63 JavaFX Zugriff auf Guiobjekte die über FXML erstellt wurden AWT, Swing, JavaFX & SWT 2
O JTextfield wird über'drawed'.. AWT, Swing, JavaFX & SWT 6
K JavaFX Fenster aufrufen über Menü AWT, Swing, JavaFX & SWT 1
J JTable aktuallisieren über anderen Frame AWT, Swing, JavaFX & SWT 6
kaoZ Swing JFrame lässt sich nicht über dispose() abbauen AWT, Swing, JavaFX & SWT 0
P Vorteile von Tooltip nutzen (wird über allen anderen Objekten angezeigt) AWT, Swing, JavaFX & SWT 3
elischa JFrame über mehrere JPanel und Listener AWT, Swing, JavaFX & SWT 17
B Swing Borderlayout East über North AWT, Swing, JavaFX & SWT 5
D Swing Letzte Zeile einer JTable nicht über RowSorter sotieren AWT, Swing, JavaFX & SWT 2
C Methode über Buttonklick starten AWT, Swing, JavaFX & SWT 8
P Swing Panel-austausch über einen MenuListener AWT, Swing, JavaFX & SWT 2
M JLabel über JButtons zeichnen AWT, Swing, JavaFX & SWT 4
P Swing Button über gesamtes Panel AWT, Swing, JavaFX & SWT 2
3 JDialog über einem Vollbildfenster anzeigen AWT, Swing, JavaFX & SWT 5
K GUI Elemente über eine separate Textdatei beschriften? AWT, Swing, JavaFX & SWT 4
A Bild über Imageviewer auf GUI anzeigen AWT, Swing, JavaFX & SWT 3
K 2D-Grafik Kontrastanpassung über einen JSlider AWT, Swing, JavaFX & SWT 2
G JScrollPane über JScrollPane AWT, Swing, JavaFX & SWT 2
L Button über/auf JTextField AWT, Swing, JavaFX & SWT 5
A Swing JTable wird nicht über zurückegebene Referenz geaddet.Wieso nicht? AWT, Swing, JavaFX & SWT 5
D JTextField über ein Game AWT, Swing, JavaFX & SWT 11
K Action Listener implementieren über Objekt AWT, Swing, JavaFX & SWT 14
bluerob Fehler bei Wertübermittlung über KeyListener AWT, Swing, JavaFX & SWT 3
R JTextField mit abgerundeten Ecken - Geht über Grenze hinaus AWT, Swing, JavaFX & SWT 4
S JDialog direkt über dem MainFrame aufpoppen lassen AWT, Swing, JavaFX & SWT 2
X Swing Panel Extra Klasse & Aufruf über Button AWT, Swing, JavaFX & SWT 18
J Frame mit Button erstellen - Warum ist es nötig, Frame über Unterklasse zu erstellen? (Reg Listener) AWT, Swing, JavaFX & SWT 2
P versch. JPanel Klassen über Menü öffnen AWT, Swing, JavaFX & SWT 12
P Öffnen, Speichern von Dat. über DialogBoxen AWT, Swing, JavaFX & SWT 10
R Bewglichen Rahmen über einem Bild AWT, Swing, JavaFX & SWT 3
P Listenelemente über Checkbox löschen AWT, Swing, JavaFX & SWT 6
H Swing "Drag and Drop" eines JComponent über ein JPanel AWT, Swing, JavaFX & SWT 2
S SWT Anzeigen einer lokalen HTML-Seite im Browser Widget über RAP nicht möglich AWT, Swing, JavaFX & SWT 3
D Label über JScrollPane AWT, Swing, JavaFX & SWT 3
M TextArea über mehrere Zeilen - wie Zeileanzahl abfragen? AWT, Swing, JavaFX & SWT 5
C Linien über GridLayout zeichnen AWT, Swing, JavaFX & SWT 3
S JDialog über Applet AWT, Swing, JavaFX & SWT 3
K Swing JButton über JLabel AWT, Swing, JavaFX & SWT 6
S AWT Skalieren von Polygon über Area klappt nicht AWT, Swing, JavaFX & SWT 4
C Etwas durchsichtig machen über einem Panel AWT, Swing, JavaFX & SWT 7
L LayoutManager Componenten über verfügbaren Platz strecken AWT, Swing, JavaFX & SWT 7
C Java-applikation über Fullscreen AWT, Swing, JavaFX & SWT 4
F Panels über buttons zu anderen Panels hinzufügen AWT, Swing, JavaFX & SWT 2
S JTable Filter nach Wort oder Wortteil über ganze Tabelle AWT, Swing, JavaFX & SWT 5
M Hover-Farbe über Hintergrundfarbe legen AWT, Swing, JavaFX & SWT 3
A Swing Gleichmäßige Verteilung der Tabellenzeilen über den gesammten Tabellenbereich AWT, Swing, JavaFX & SWT 5
S JButton und textfield.setText - Komponenten über-/verdecken sich AWT, Swing, JavaFX & SWT 15
S JButton -> Text über Icon AWT, Swing, JavaFX & SWT 4
P Swing Componente über Rahmen hinaus zeichnen AWT, Swing, JavaFX & SWT 2
K JButton nur dann aktivieren, wenn die Mouse 3 Sek. über dem Button bleibt AWT, Swing, JavaFX & SWT 2
B JFrame: Benachrichtung über Größenänderung AWT, Swing, JavaFX & SWT 4
J Schließen über x soll zwei Prozesse beenden AWT, Swing, JavaFX & SWT 7

Ähnliche Java Themen

Neue Themen


Oben