Swing Scrollen über JPane

Amios

Mitglied
Hallo, ich habe mir eine von JPane erbende Klasse erstellt, die so aussieht
Java:
public class JImagePanel extends JPanel{

	  private Image img;

	  public JImagePanel(String img) {
	    this(new ImageIcon(img).getImage());
	  }

	  public JImagePanel(Image img) {
	    this.img = img;
	    Dimension size = new Dimension(img.getWidth(null), img.getHeight(null));
	    setPreferredSize(size);
	    setMinimumSize(size);
	    setMaximumSize(size);
	    setSize(size);
	    setLayout(null);
	  }

	  public void paintComponent(Graphics g) {
	    g.drawImage(img, 0, 0, null);
	  }

	}
nun instantiiere ich ein solches und füge ich in dieses Panel beliebige SwingObjecte ein (was auch funktioniert).
Ich möchte jedoch, wenn der Anzeigebereich erschöpft ist, eine Scrollbar angezeigt bekommen und mit dieser über den Inhalt des Panels scrollen können( der Background soll sich nicht verändern).

Daher habe ich eine JScrollbar erstellt und als View jenes JImagePane zugewiesen.
Java:
JImagePanel cardpanel = new JImagePanel("./spielflaeche.gif");
JScrollPane scrollpane = new JScrollPane(cardpanel);
Jedoch kann ich nicht über die Elemente scrollen. Wo dran mag das liegen?
 

MQue

Top Contributor
Es liegt daran, dass su der JScrollPane eine size (width, height) geben musst -> z.B.: JScrollPane#setSize(width, height);
 
Zuletzt bearbeitet:

Amios

Mitglied
Danke, ich habe nun

Java:
scrollpane.setSize(cardpanel.getSize());

zum Quellcode hinzugefügt, jedoch ohne Auswirkungen.
 

MQue

Top Contributor
Was ist wenn du die JScrollPane etwas kleiner als cardpanel.getSize() machst, Dann müssten die ScrollBars schonmal sichtbar sein.
 

Amios

Mitglied
Java:
scrollpanel.setSize((int) cardpanel.getSize().getWidth()-50, (int) (cardpanel.getSize().getHeight()));
keine Änderung.

ich poste mal grade den kompletten Code meiner Klass
Java:
public class PlayerGui extends Thread {
	private int tableID = 0;
	private boolean isAlive = true;
	
	private LinkedBlockingQueue<Card> cards = null;

	private JFrame frame = null;
	private JMenuBar menubar = null;
	private JMenuItem exit;
	private JRadioButtonMenuItem show;
	private JMenu data;
	private JMenu view;
	private JMenu help;
	private JPanel mainpanel = null;
	private JPanel buttons = null;
	private JButton check = null;
	private JButton allin = null;
	private JButton flod = null;
	private JButton raise = null;
	private JTextField raisamount = null;
	private JScrollPane scrollpanel = null;
	private JPanel cardpanel = null;
	private Logger log = null;

	public PlayerGui(int tableID) {
		this.tableID = tableID;
		cards = new LinkedBlockingQueue<Card>();
		this.log = new Logger(this);
		log.setDateFormat(Setup.DATEFORMAT);
		log.setStandardLoggingPath(Setup.loggingPath + "/"
				+ this.getClass().getSimpleName() + ".log");
		log.setErrorLoggingPath(Setup.loggingPath + "/"
				+ this.getClass().getSimpleName() + ".err.log");
		setup();
	}

	public void setup() {
		frame = new JFrame("IViRNN Table:" + tableID);
		mainpanel = new JPanel();
		
		menubar = new JMenuBar();
		data = new JMenu("Datei");
		view = new JMenu("Ansicht");
		help = new JMenu("Hilfe");
		exit = new JMenuItem("Tisch verlassen");
		show = new JRadioButtonMenuItem("Serverinfo einblenden");
		
		buttons = new JPanel();
		check = new JButton("check");
		allin = new JButton("All-in");
		flod = new JButton("flod");
		raisamount = new JTextField("0");
		raise = new JButton("raise");
		
		cardpanel = new JImagePanel(initBackgroundImage());
		cardpanel = new JPanel();
		scrollpanel = new JScrollPane(cardpanel);
	}

	public void init() {
		addActionListeners();
//		scrollpanel.setVisible(true);
		scrollpanel.setSize((int) cardpanel.getSize().getWidth()-50, (int) (cardpanel.getSize().getHeight()));
		cardpanel.setLayout(new FlowLayout());
		
		raisamount.setSize(raise.getSize());

		buttons.add(allin);
		buttons.add(flod);
		buttons.add(raise);
		buttons.add(raisamount);
		buttons.add(check);

		mainpanel.setLayout(new BorderLayout());
		mainpanel.add(scrollpanel, BorderLayout.CENTER);
		mainpanel.add(buttons, BorderLayout.SOUTH);

		data.add(exit);
		data.setMnemonic('D');
		view.add(show);
		view.setMnemonic('A');
		show.setSelected(true);

		menubar.add(data);
		menubar.add(view);
		menubar.add(help);

		frame.getContentPane().add(mainpanel);
		frame.setLocationRelativeTo(null);
		frame.setIconImage(new ImageIcon(Setup.PATH + "icon.gif").getImage());
		frame.setResizable(false);
		frame.setJMenuBar(menubar);
		frame.setVisible(true);
	}

	private String initBackgroundImage() {
		File f = new File("./CardImages/Felt.gif");
		if (f.exists()) {
			return f.getAbsolutePath();
		} else {
			System.err.println("File does not exist");
		}
		throw new FileNotFoundException();
	}

	private void addActionListeners() {
		exit.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				// ln.shutdown();
			}
		});

		// frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.addWindowListener(new WindowAdapter() {
			public void windowClosing(WindowEvent we) {
				/* ln.shutdown(); */
			}
		});
	}

	@Override
	public void run() {
		init();
		try {
			while (isAlive) {
				Card c = cards.take();
				showCard(c);
				frame.pack();

			}
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}

	public synchronized void addCard(Card card) {
		cards.add(card);
		log.logDebug("Karte " + card.getColor() + "-" + card.getValue()
				+ " wurde erhalten");
	}

	private void showCard(Card c) {
		Icon image = c.getImage();
		if (c != null) {
			JLabel l = new JLabel(image);
			JLabel text = new JLabel();
			text.setText(c.getColor() + "-" + c.getValue());
			l.add(text);
			cardpanel.add(l);
		} else {
			log.logError("Card image was not found");
		}
	}

	public static void main(String[] args) {
		PlayerGui pg = new PlayerGui(182);
		pg.start();
		Deck d = new Deck();
		d.shuffle();
		for (int i = 0; d.size() != 0; i++) {
			pg.addCard(d.drawCard());
		}

	}
}
 
Zuletzt bearbeitet:

Amios

Mitglied
ja, ich denke, dass es nicht nötig ist die Scrollpane extra sichtbar zu machen(ist sie glaube ich standartmäßig). aber ich habe die Kommentare weg genommen -> keine Änderung

ich vermute, dass das problem im frame.pack() im run() liegt.
 
Zuletzt bearbeitet:

MQue

Top Contributor
So funktionierts (ich hab deine Version jetzt mal ziemlich abgespckt und auf das Wesentliche reduziert), Du darfst die Komponente bei der JScrollPane nicht direkt über den Konstruktor hinzufügen sondern musst es über den ViewPort machen, sollte es dann noch immer nicht funktionieren, musst du noch die PreferedSize setzen, dann sollte es klappen.
lg


Java:
package classpathtest;

import java.awt.Color;
import java.awt.Dimension;
import java.io.FileNotFoundException;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.logging.Logger;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JRadioButtonMenuItem;
import javax.swing.JScrollPane;
import javax.swing.JTextField;

public class PlayerGui {

    private static class JImagePanel extends JPanel {

        public JImagePanel(String initBackgroundImage) {
            super();
        }
    }

    private int tableID = 0;
    private boolean isAlive = true;
    private LinkedBlockingQueue<Card> cards = null;
    private JFrame frame = null;
    private JMenuBar menubar = null;
    private JMenuItem exit;
    private JRadioButtonMenuItem show;
    private JMenu data;
    private JMenu view;
    private JMenu help;
    private JPanel mainpanel = null;
    private JPanel buttons = null;
    private JButton check = null;
    private JButton allin = null;
    private JButton flod = null;
    private JButton raise = null;
    private JTextField raisamount = null;
    private JScrollPane scrollpanel = null;
    private JPanel cardpanel = null;
    private Logger log = null;

    public PlayerGui(int tableID) throws FileNotFoundException {
        this.tableID = tableID;
        cards = new LinkedBlockingQueue<Card>();
        init();
        }

    public void init() {      
        frame = new JFrame("IViRNN Table:" + tableID);

        cardpanel = new JImagePanel("");
        cardpanel = new JPanel();
        cardpanel.setBackground(new Color(255, 0, 0));
        
        scrollpanel = new JScrollPane();
        scrollpanel.setBackground(new Color(0,255, 0));
        cardpanel.setSize(600, 600);
        cardpanel.setPreferredSize(new Dimension(800, 900));
        scrollpanel.setSize(400, 400);
        scrollpanel.getViewport().add(cardpanel);
        scrollpanel.setPreferredSize(new Dimension(400, 400));
        scrollpanel.revalidate();

        frame.getContentPane().add(scrollpanel);
        frame.setLocationRelativeTo(null);
        frame.setJMenuBar(menubar);
        frame.getContentPane().setBackground(new Color(0, 0, 255));
        frame.setBackground(new Color(100,100,255));
        frame.setBounds(200, 200, 400, 400);
        frame.setPreferredSize(new Dimension(400, 400));
        frame.setVisible(true);
    }

    public static void main(String[] args) throws FileNotFoundException {
        PlayerGui pg = new PlayerGui(182);
    }
}
 
Zuletzt bearbeitet:

Amios

Mitglied
Super danke, nun habe ich Scrollbars.
Leider jedoch nicht so wie ich sie haben wollte, denn es kann nicht über alle Karten gescrollt werden.
Ich habe mal einen screenshot angehängt, um zu zeigen, was ich meine.

playerscreen.jpg
 

Amios

Mitglied
Danke! Doch trotz der Größenänderung, ändert sich nichts.
Außerdem habe ich es mir anders vorgestellt.
Ich wollte, dass der Grüne Hintergrund statisch bleibt, wenn gescrollt wird.
Die Karten sollten paarweise mittig auf dem Hintergrund platziert werden.
Anschließend soll es nur eine Vertikale Scrollbar geben, mit der über allle Kartenpaare gescrollt werden kann.

ich habe mir dabei gedacht, ich mache mir mehrere Areale, die jeweils ein Panel beinhalten.
Das erste ist das mainpanel, es besitzt ein BorderLayout und stellt also die Wurzel des Objecttrees da.
Das die unterschiedlichen Areale des mainpanels sehen wie folgt aus: center->Karten, south->knöppe.
Daher habe ich im Center das Cardpanel hinzugefügt, welches meinen Hintergrund zeigt.
Davor sollte eigentlich nun eine Komponente liegen, dessen Hintergrund transparent ist und welche die eigentlichen Karten anzeigt, und das zudem scrollbar ist. Um diese Komponente zu realisieren könnte ein JLabel genommen werden, jedoch weiß ich nicht, ob ein JLabel die Kriterien erfüllt, die ich letztlich haben möchte.
 

Marco13

Top Contributor
setSize braucht man "fast nie". Wenn man einen LayoutManager verwendet, sollte alles mit setPreferredSize zu erledigen sein. Insgesamt klingt das, was du beschrieben hast, sehr speziell. Vielleicht würde eine Skizze helfen... :bahnhof:
 

Amios

Mitglied
Gute Idee! Aussehen soll es so:

playerscreenshouldbe.jpg


P.S. zudem soll, wie bereits erwähnt, der grüne Hintergrund statisch bleiben.

Update: Ich habe nun den gewünschten Look, jedoch wieder nicht ohne Problem. beim Scrollen und hinzufügen der Karten werden weder das Cardpanel noch der Hintergrund neu gezeichnet. Sprich, es verschwimmt alles.
 
Zuletzt bearbeitet:

Marco13

Top Contributor
OK, zu erreichen, dass dieser Scrollbare Teil in der mitte "schwebt" könnte ein bißchen Fummelig werden - am einfachsen wahrscheinlich durch ein BorderLayout zu erreichen, bei dem das Scroll-Ding im CENTER liegt, und an NORTH, SOUTH, EAST und WEST jeweils ein durchsichtiges JPanel...

Wie hast du das neuzeichnen und so jetzt gemacht, wo du von "verschmieren" redest?
 

Amios

Mitglied
Also, ich poste mal die Code ausschnitte, die ich verändert bzw. hinzugefügt habe.

Java:
	private void init() {
		addActionListeners();
		FlowLayout layout = new FlowLayout();
		cardPanel.setLayout(layout);
		cardPanel.setBackground(new Color(100, 100, 100, 0));
		cardPanel.setBorder(null);
		
		scrollpanel.getViewport().add(cardPanel);
		scrollpanel.setBackground(new Color(100, 100, 100, 0));
//		scrollpanel.setViewportBorder(null);
		scrollpanel.setBorder(null);
		scrollpanel.getVerticalScrollBar();
		
		raisamount.setSize(raise.getSize());

		buttons.add(allin);
		buttons.add(flod);
		buttons.add(raise);
		buttons.add(raisamount);
		buttons.add(check);
		
		field.setLayout(new FlowLayout());
		field.add(scrollpanel, BorderLayout.CENTER);
		
		mainpanel.setLayout(new BorderLayout());
		mainpanel.add(field, BorderLayout.CENTER);
		mainpanel.add(buttons, BorderLayout.SOUTH);

		data.add(exit);
		data.setMnemonic('D');
		view.add(show);
		view.setMnemonic('A');
		show.setSelected(true);

		menubar.add(data);
		menubar.add(view);
		menubar.add(help);

		frame.getContentPane().add(mainpanel);
		frame.setLocationRelativeTo(null);
		frame.setIconImage(new ImageIcon(Setup.PATH + "icon.gif").getImage());
		frame.setJMenuBar(menubar);
	}

        @Override
	@Deprecated
	public void run() {
		try {
			init();
			while (isAlive) {
				Card c = cards.take();
				showCard(c);
				updateUI();

			}
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
	
	private void updateUI(){
		scrollpanel.setHorizontalScrollBar(null);
		FlowLayout layout = (FlowLayout) cardPanel.getLayout();
		cardPanel.setPreferredSize(new Dimension((int) cardSize.getWidth() * 2,
				(int) (cardSize.getHeight() + layout.getVgap())
						* cardPanel.getComponentCount() / 2));
		scrollpanel.setPreferredSize(new Dimension(
				(int) cardSize.getWidth() * 2 + 30,
				(int) cardSize.getHeight() + 10));
		cardPanel.revalidate();
		frame.setVisible(true);
		frame.pack();
	}

sieht dann so aus:


da sieht man auch gut die Schlieren oder das Verschwimmen:)
 

Amios

Mitglied
Ich habe mal auf die schnelle ein KSKB zusammen gerödelt.... nun wenn es mal ein KSKB wäre.
Java:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.Image;
import java.util.concurrent.LinkedBlockingQueue;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;

public class Gui extends Thread{
 
	private JFrame frame = null;
	private JScrollPane scroll = null;
	private JPanel componentPanel = null;
	private JImagePanel imagepane= null;
	private LinkedBlockingQueue<JComponent> queue= null; 
	public Gui() {
	}
	
	@Override
	public void run() {
		initGui();
		while(true) {
			JComponent component;
			try {
				component = queue.take();
				showComponent(component);
				updateUI(component);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}

	private void initGui() {
		queue = new LinkedBlockingQueue<JComponent>();
		frame = new JFrame("GUI");
		scroll = new JScrollPane();
		componentPanel = new JPanel();
		imagepane = new JImagePanel("./background.png");
		
		FlowLayout layout = new FlowLayout();
		layout.setVgap(50);
		componentPanel.setLayout(layout);
		componentPanel.setBackground(new Color(100, 100, 100, 0));
		componentPanel.setBorder(null);
		
		scroll.getViewport().add(componentPanel);
		scroll.setBackground(new Color(100, 100, 100, 0));
		scroll.setBorder(null);
		
		imagepane.setLayout(new FlowLayout());
		imagepane.setBackground(new Color(100, 100, 100, 0));
		imagepane.add(scroll);
		
		frame.setLayout(new BorderLayout());
		frame.add(imagepane, BorderLayout.CENTER);
		
		
		
		
	}

	public synchronized void showComponent(JComponent component) {
		componentPanel.add(component);
	}
	private void updateUI(JComponent lastcomponent) {
		scroll.setHorizontalScrollBar(null);
		FlowLayout layout = (FlowLayout) componentPanel.getLayout();
		System.out.println(lastcomponent.getPreferredSize().height);
		componentPanel.setPreferredSize(new Dimension(lastcomponent.getPreferredSize().width * 2,
				(int) (lastcomponent.getPreferredSize().height + layout.getVgap())
						* componentPanel.getComponentCount() / 2));
		scroll.setPreferredSize(new Dimension(
				(int) componentPanel.getPreferredSize().width +(layout.getHgap()*2) + scroll.getVerticalScrollBar().getWidth()+2,
				(int) lastcomponent.getPreferredSize().height));
		componentPanel.revalidate();
		frame.setVisible(true);
		frame.pack();
		
	}
	
	public void addComponent(JComponent comp) {
		try {
			this.queue.put(comp);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
	
	
	public class JImagePanel extends JPanel{
		 private Image img;

		  public JImagePanel(String img) {
		    this(new ImageIcon(img).getImage());
		  }

		  public JImagePanel(Image img) {
		    this.img = img;
		    Dimension size = new Dimension(img.getWidth(null), img.getHeight(null));
		    setPreferredSize(size);
		    setMinimumSize(size);
		    setMaximumSize(size);
		    setSize(size);
		    setLayout(null);
		  }

		  public void paintComponent(Graphics g) {
		    g.drawImage(img, 0, 0, null);
		  }
	}
	
	public static void main(String[] args) {
		Gui g = new Gui();
		g.start();
		for (int i = 0; i < 10; i++) {
			JButton t = new JButton("Button:"+i);
			t.setPreferredSize(new Dimension(100, 100));
			g.addComponent(t);
		}
	}
}

p.S.Was wichtig ist, ist dass der von mir oben beschriebene Effekt auftritt wenn man scrollt.
Die Button verschlirren den Zwischenraum des Layouts.
 
Zuletzt bearbeitet:

Marco13

Top Contributor
Das enthält immernoch den Teil, der bei mir beim "Original" die meisten ???:L :autsch: ???:L 's verursacht hat: Was ist das mit der Queue und dem Thread und dem updateUI denn für ein seltsames Konstrukt? Ich steig' da nicht durch :bahnhof: Sollen die Karten (von einem anderen Thread irgendwie) da reingelegt werden? Was soll der Anlass dafür sein?

Hab mal was gebastelt, vielleicht meinst du ja sowas...?
Java:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.*;
import java.awt.Image;
import java.util.concurrent.LinkedBlockingQueue;

import javax.swing.*;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;

public class GuiBug2 {

    private JPanel cardPairsPanel = null;
    private JScrollPane scrollPane = null;
    private static final int HGAP = 10;
    private static final int VGAP = 10;

    public GuiBug2()
    {
        JFrame frame = new JFrame("GUI");
        frame.setLayout(new BorderLayout());

        JPanel imagePanel = new JImagePanel("image01.png");
        frame.add(imagePanel, BorderLayout.CENTER);

        cardPairsPanel = new JPanel(new GridLayout(0,2,HGAP,VGAP));
        cardPairsPanel.setBorder(
            BorderFactory.createEmptyBorder(0,HGAP,0,HGAP));

        scrollPane = new JScrollPane(cardPairsPanel);
        imagePanel.add(scrollPane);

        frame.pack();
        frame.setVisible(true);
    }

    public void addComponents(JComponent c0, JComponent c1)
    {
        cardPairsPanel.add(c0);
        cardPairsPanel.add(c1);

        int w =
            cardPairsPanel.getPreferredSize().width +
            scrollPane.getVerticalScrollBar().getPreferredSize().width + HGAP;
        int h = Math.max(
            c0.getPreferredSize().height,
            c0.getPreferredSize().height)+VGAP;
        Dimension d = new Dimension(w,h);
        scrollPane.setPreferredSize(d);
        scrollPane.validate();
    }


    public class JImagePanel extends JPanel
    {
         private Image img;

          public JImagePanel(String img)
          {
            this(new ImageIcon(img).getImage());
          }

          public JImagePanel(Image img) {
            this.img = img;
            Dimension size = new Dimension(img.getWidth(null), img.getHeight(null));
            setPreferredSize(size);
            setMinimumSize(size);
            setMaximumSize(size);
            setSize(size);
            setLayout(new FlowLayout());
          }

          public void paintComponent(Graphics g)
          {
              super.paintComponent(g);
            g.drawImage(img, 0, 0, null);
          }
    }

    public static void main(String[] args)
    {
        SwingUtilities.invokeLater(new Runnable()
        {
            public void run()
            {
                GuiBug2 g = new GuiBug2();
                for (int i = 0; i < 10; i++)
                {
                    JButton t0 = new JButton("ButtonA:"+i);
                    JButton t1 = new JButton("ButtonB:"+i);
                    t0.setPreferredSize(new Dimension(100, 100));
                    t1.setPreferredSize(new Dimension(100, 100));
                    g.addComponents(t0, t1);
                }
            }
        });
    }
}
 

Amios

Mitglied
Ja, ein anderer Thread übergibt der UI die Karten.
Daher ist die UI ein eigenständiger Thread, der selbstständig die Karten in dem Cardpanel anzeigt.

Ich habe mal deinen Code genommen und verändert, wie ich ihn nutzen würde(Hintergrund auf 100% Tranzparenz beim cardPairsPanel und beim scrollPane gesetzt.
Starte den Code, scroll ein wenig rum und du wirst sehen was ich meine.

Java:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.*;
import java.awt.Image;
 
import javax.swing.*;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;
 
public class GuiBug2 {
 
    private JPanel cardPairsPanel = null;
    private JScrollPane scrollPane = null;
    private static final int HGAP = 10;
    private static final int VGAP = 10;
 
    public GuiBug2()
    {
        JFrame frame = new JFrame("GUI");
        frame.setLayout(new BorderLayout());
 
        JPanel imagePanel = new JImagePanel("image01.png");
        frame.add(imagePanel, BorderLayout.CENTER);
 
        cardPairsPanel = new JPanel(new GridLayout(0,2,HGAP,VGAP));
        cardPairsPanel.setBorder(
            BorderFactory.createEmptyBorder(0,HGAP,0,HGAP));
/*Transparenz für cardPairsPanel*/
        cardPairsPanel.setBackground(new Color(100, 100, 100, 0));
        scrollPane = new JScrollPane(cardPairsPanel);
/*Transparenz für scrollPane*/
        scrollPane.setBackground(new Color(100, 100, 100, 0));
        imagePanel.add(scrollPane);
 
        frame.pack();
        frame.setVisible(true);
    }
 
    public void addComponents(JComponent c0, JComponent c1)
    {
        cardPairsPanel.add(c0);
        cardPairsPanel.add(c1);
 
        int w =
            cardPairsPanel.getPreferredSize().width +
            scrollPane.getVerticalScrollBar().getPreferredSize().width + HGAP;
        int h = Math.max(
            c0.getPreferredSize().height,
            c0.getPreferredSize().height)+VGAP;
        Dimension d = new Dimension(w,h);
        scrollPane.setPreferredSize(d);
        scrollPane.validate();
    }
 
 
    public class JImagePanel extends JPanel
    {
         private Image img;
 
          public JImagePanel(String img)
          {
            this(new ImageIcon(img).getImage());
          }
 
          public JImagePanel(Image img) {
            this.img = img;
            Dimension size = new Dimension(img.getWidth(null), img.getHeight(null));
            setPreferredSize(size);
            setMinimumSize(size);
            setMaximumSize(size);
            setSize(size);
            setLayout(new FlowLayout());
          }
 
          public void paintComponent(Graphics g)
          {
              super.paintComponent(g);
            g.drawImage(img, 0, 0, null);
          }
    }
 
    public static void main(String[] args)
    {
        SwingUtilities.invokeLater(new Runnable()
        {
            public void run()
            {
                GuiBug2 g = new GuiBug2();
                for (int i = 0; i < 10; i++)
                {
                    JButton t0 = new JButton("ButtonA:"+i);
                    JButton t1 = new JButton("ButtonB:"+i);
                    t0.setPreferredSize(new Dimension(100, 100));
                    t1.setPreferredSize(new Dimension(100, 100));
                    g.addComponents(t0, t1);
                }
            }
        });
    }
}
 
Zuletzt bearbeitet:

Marco13

Top Contributor
Das Hauptproblem mit den Thread ist: ALLE Operationen, die das Aussehen von Swing-Components verändern (oder auf dem Aussehen von Swing-Components basieren) MÜSSEN vom Event-Dispatch-Thread gemacht werden - man kann also nicht mit einem anderen Thread irgendwelche add/remove(Component)-Aufrufe oder LayoutÄnderungen machen. Deswegen hatte ich den Inhalt der main in die SwingUtilities eingewickelt - und die sind auch die Lösung für dieses Problem.

(BTW: Statt mit einer durchsichtigen Farbe zu zeichnen, kann man auch setOpaque(false) machen - vielleicht würde das mit der Farbe aber auch gehen, wenn man sie auch für den ViewPort setzen würde)

Java:
// From [url]http://www.java-forum.org/awt-swing-swt/111447-scrollen-ueber-jpane.html[/url]

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.*;
import java.awt.Image;

import javax.swing.*;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;

public class GuiBug3 {

    private JFrame frame = null;
    private JPanel cardPairsPanel = null;
    private JScrollPane scrollPane = null;
    private static final int HGAP = 10;
    private static final int VGAP = 10;

    public GuiBug3()
    {
        frame = new JFrame("GUI");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLayout(new BorderLayout());


        JPanel imagePanel = new JImagePanel("bildB.jpg");
        frame.add(imagePanel, BorderLayout.CENTER);

        cardPairsPanel = new JPanel(new GridLayout(0,2,HGAP,VGAP));
        cardPairsPanel.setBorder(
            BorderFactory.createEmptyBorder(0,HGAP,0,HGAP));
        cardPairsPanel.setOpaque(false); /*Transparenz für cardPairsPanel*/
        scrollPane = new JScrollPane(cardPairsPanel);
        scrollPane.setVerticalScrollBarPolicy(
            JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
        scrollPane.setOpaque(false); /*Transparenz für scrollPane*/
        scrollPane.getViewport().setOpaque(false); /*Transparenz für scrollPane*/
        scrollPane.setBorder(null);
        imagePanel.add(scrollPane);

        frame.pack();
        frame.setVisible(true);
    }

    public void addComponents(JComponent c0, JComponent c1)
    {
        cardPairsPanel.add(c0);
        cardPairsPanel.add(c1);

        int w =
            cardPairsPanel.getPreferredSize().width +
            scrollPane.getVerticalScrollBar().getPreferredSize().width + HGAP;
        int h = Math.max(
            c0.getPreferredSize().height,
            c0.getPreferredSize().height)+VGAP;
        Dimension d = new Dimension(w,h);
        scrollPane.setPreferredSize(d);
        frame.validate();
        frame.repaint();
    }


    public class JImagePanel extends JPanel
    {
         private Image img;

          public JImagePanel(String img)
          {
            this(new ImageIcon(img).getImage());
          }

          public JImagePanel(Image img) {
            this.img = img;
            Dimension size = new Dimension(img.getWidth(null), img.getHeight(null));
            setPreferredSize(size);
            setMinimumSize(size);
            setMaximumSize(size);
            setSize(size);
            setLayout(new FlowLayout());
          }

          public void paintComponent(Graphics g)
          {
              super.paintComponent(g);
            g.drawImage(img, 0, 0, null);
          }
    }

    public static void main(String[] args)
    {
        SwingUtilities.invokeLater(new Runnable()
        {
            public void run()
            {
                createGui();
            }
        });
    }

    // Must be called on EDT
    private static void createGui()
    {
        GuiBug3 g = new GuiBug3();
        startAddingThread(g);
    }

    private static void startAddingThread(final GuiBug3 g)
    {
        Thread t = new Thread(new Runnable()
        {
            public void run()
            {
                for (int i = 0; i < 20; i++)
                {
                    addCards(g, i);
                    try
                    {
                        Thread.sleep(500);
                    }
                    catch (InterruptedException e)
                    {
                        Thread.currentThread().interrupt();
                        return;
                    }
                }
            }
        });
        t.start();
    }

    // May be called from any Thread
    private static void addCards(final GuiBug3 g, final int i)
    {
        System.out.println("Adding "+i);
        SwingUtilities.invokeLater(new Runnable()
        {
            public void run()
            {
                JButton t0 = new JButton("ButtonA:"+i);
                JButton t1 = new JButton("ButtonB:"+i);
                t0.setPreferredSize(new Dimension(100, 100));
                t1.setPreferredSize(new Dimension(100, 100));
                g.addComponents(t0, t1);
            }
        });
    }

}
 

Amios

Mitglied
Super! vielen, vielen Dank Marko13. setOpaque(false) statt setBackground(new Color(100, 100, 100, 0)) hat das Problem gelöst.

Danke wirklich!
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
volcanos Scrollen: JScrollPane mit Graphics g und Java-Fonts extends Frame ? AWT, Swing, JavaFX & SWT 5
P kein Scrollen nach affinertransformation bei mouse dragged AWT, Swing, JavaFX & SWT 2
S JavaFX JavaFX TableView scrollen färbt falsche Zeilen AWT, Swing, JavaFX & SWT 1
S Nach scrollen verschwindet das zuvor im JPanel gezeichnete AWT, Swing, JavaFX & SWT 2
J JList scrollen AWT, Swing, JavaFX & SWT 3
Bluedaishi JTextArea gefundene Zeile nach Oben Scrollen AWT, Swing, JavaFX & SWT 13
P Swing Horizontales Scrollen mit Shift-Mausrad AWT, Swing, JavaFX & SWT 2
N Swing Problem beim Scrollen mit JScrollPane AWT, Swing, JavaFX & SWT 6
W JavaFX Scrollpane elementweise scrollen AWT, Swing, JavaFX & SWT 4
Thallius Automatisches Scrollen zum aktiven JTextView klappt nicht AWT, Swing, JavaFX & SWT 2
J Swing JTextPane mit JScrollPane auf JPanel scrollen nicht AWT, Swing, JavaFX & SWT 6
W Swing Zum Ende einer Scrollpane scrollen AWT, Swing, JavaFX & SWT 2
S JScrollPane --> Programm hängt sich beim scrollen auf AWT, Swing, JavaFX & SWT 2
S JavaFX Mehrere TreeTableView's synchron scrollen AWT, Swing, JavaFX & SWT 0
O Tabelle "animiert" Scrollen AWT, Swing, JavaFX & SWT 1
O Swing JTable per Scrollen füllen! AWT, Swing, JavaFX & SWT 7
J AWT choice mit viel Auswahl aktualisiert sich nicht korrekt beim scrollen?! AWT, Swing, JavaFX & SWT 3
P Durch Bilder Scrollen AWT, Swing, JavaFX & SWT 2
U Swing JPane und JScrollpane in JSplitpane-Seite: Scrollen funktioniert nicht AWT, Swing, JavaFX & SWT 3
J JTable wird bei scrollen falsch gezeichnet AWT, Swing, JavaFX & SWT 3
N Touchscreen-Scrollen, wo liegt der Fehler? AWT, Swing, JavaFX & SWT 3
S Swing Scrollpanes: wie kann ich durch Java-Code an den "Anfang" scrollen AWT, Swing, JavaFX & SWT 8
G JTable zentriert scrollen AWT, Swing, JavaFX & SWT 2
D SWING - Ein Composite scrollen AWT, Swing, JavaFX & SWT 6
S Canvas in ScrollPane wird beim scrollen immer neu gezeichnet AWT, Swing, JavaFX & SWT 3
D Swing JScrollbar ganz nach unten scrollen AWT, Swing, JavaFX & SWT 2
K SWT treeviewer scrollen AWT, Swing, JavaFX & SWT 8
F Swing Mehrere Textfelder in Scrollpane einfügen und dann zum Scrollen bringen? AWT, Swing, JavaFX & SWT 4
J Lazy Loading eine JTree während Scrollen AWT, Swing, JavaFX & SWT 11
Dit_ JTextArea zu Zeile X scrollen AWT, Swing, JavaFX & SWT 4
S SWT Zwei Tabellen gleichzeitig Scrollen AWT, Swing, JavaFX & SWT 3
Dragonfire Swing JPanel nur vertikal scrollen AWT, Swing, JavaFX & SWT 4
hdi SWT ScrolledComposite -> Nix mit Scrollen? AWT, Swing, JavaFX & SWT 8
T In einem Label scrollen AWT, Swing, JavaFX & SWT 3
A Swing JScrollPane ans ende Scrollen AWT, Swing, JavaFX & SWT 9
W SwingX Problem mit Scrollen von 2 JXTaskPaneContainer AWT, Swing, JavaFX & SWT 3
S Swing Scrollen ohne Leiste? AWT, Swing, JavaFX & SWT 2
J wie Scrollen? AWT, Swing, JavaFX & SWT 3
R Zu selektiertem Column in JTable scrollen? AWT, Swing, JavaFX & SWT 2
P Drei Scrollpanes gleichzeitig scrollen AWT, Swing, JavaFX & SWT 3
G Scrollen per mouseDragged (JScrollPane) AWT, Swing, JavaFX & SWT 8
H jScrollPane ohne Scrollen AWT, Swing, JavaFX & SWT 2
G Mehrere JScrollPanes gekoppelt scrollen AWT, Swing, JavaFX & SWT 2
G JTable in JScrollPane - nach unten scrollen AWT, Swing, JavaFX & SWT 11
S JList automatisch scrollen AWT, Swing, JavaFX & SWT 8
D JScrollPane incl. thumbnails, soll fluessig scrollen! AWT, Swing, JavaFX & SWT 3
J JScrollPane soll automatisch zu einem punkt scrollen AWT, Swing, JavaFX & SWT 4
P JPopupMenu scrollen AWT, Swing, JavaFX & SWT 2
J JList Scrollen AWT, Swing, JavaFX & SWT 8
M PerformanceProbleme(Beim Scrollen ruckelt es) AWT, Swing, JavaFX & SWT 16
Z JTable automatisch zu einer Zeile scrollen AWT, Swing, JavaFX & SWT 4
D JScrollPane mit Grafiken scrollen lassen AWT, Swing, JavaFX & SWT 2
G 3 oder mehr JTable nebeneinander gleichzeitig vert. scrollen AWT, Swing, JavaFX & SWT 4
R JTextPane scrollen vermeiden AWT, Swing, JavaFX & SWT 2
S JScrollPane > JPanel - automatisch scrollen AWT, Swing, JavaFX & SWT 2
R Einstellen der Maus Rad Geschwindigkeit beim Scrollen AWT, Swing, JavaFX & SWT 3
I In JPopupMenu scrollen AWT, Swing, JavaFX & SWT 4
S Scrollen AWT, Swing, JavaFX & SWT 2
Q ||| Scrollen mal anders - Console mitscrollender Text??? AWT, Swing, JavaFX & SWT 6
G Problem mit horizontal und vertikal scrollen AWT, Swing, JavaFX & SWT 2
M Scrollen - Geschwindigkeit - Scrollgeschwindigkeit AWT, Swing, JavaFX & SWT 2
G JScrollPane - scrollen mit Pfeiltasten AWT, Swing, JavaFX & SWT 3
J Wie kann man beim BoxLayout scrollen? Keine Scrollleiste!:-( AWT, Swing, JavaFX & SWT 7
R JTable zu einem bestimmten Eintrag automatisch scrollen? AWT, Swing, JavaFX & SWT 2
A Scrollpane verschmiert beim scrollen AWT, Swing, JavaFX & SWT 5
S Position von Labels, Buttons, etc. festsetzen und Scrollen AWT, Swing, JavaFX & SWT 4
N JTable scrollen AWT, Swing, JavaFX & SWT 4
F 3 JTextAreas zusammen scrollen AWT, Swing, JavaFX & SWT 5
O JScrollPane beinhaltet JPanel mit null Layout kein Scrollen AWT, Swing, JavaFX & SWT 3
G Scrollen ohne scrolleisten AWT, Swing, JavaFX & SWT 5
T JTextPane in JScrollPane NICHT autom. nach unten scrollen AWT, Swing, JavaFX & SWT 3
M JScrollPane immer bis ganz nach unten scrollen lassen AWT, Swing, JavaFX & SWT 5
J Streifen beim Scrollen AWT, Swing, JavaFX & SWT 3
F Scrollen bei JTextArea in einem Null-Layout? Unmöglich? AWT, Swing, JavaFX & SWT 4
M JScrollPane soll automatisch scrollen AWT, Swing, JavaFX & SWT 5
N JScrollPane schneller scrollen AWT, Swing, JavaFX & SWT 3
V Automatisches Scrollen bei JScrollPane AWT, Swing, JavaFX & SWT 10
N Scrollen in einem Panel AWT, Swing, JavaFX & SWT 5
S jScrollPane ganz nach unten scrollen AWT, Swing, JavaFX & SWT 4
B In JScrollPane eingebettetes JEditorPane scrollen AWT, Swing, JavaFX & SWT 2
M Scrollprobleme - Panelinhalte bleiben beim Scrollen AWT, Swing, JavaFX & SWT 2
Z JTextArea in JScrollPane automatisch scrollen AWT, Swing, JavaFX & SWT 2
K JPanle scrollen . AWT, Swing, JavaFX & SWT 2
V Probleme beim Scrollen ein JPanels mit JScrollPane AWT, Swing, JavaFX & SWT 2
G JTable automatisch scrollen AWT, Swing, JavaFX & SWT 4
S Automatisches Scrollen in einer JTextArea AWT, Swing, JavaFX & SWT 6
A Scrollen von Fenster geht nicht AWT, Swing, JavaFX & SWT 4
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

Ähnliche Java Themen

Neue Themen


Oben