JButton in einem Array aktualisieren

Ardam

Mitglied
Hallo liebe Community,

für ein Projekt baue ich mir gerade eine GUI auf. Genauer gesagt habe ich ein JFrame, in dem sich zwei Panels befinden, in denen sich wiederum jeweils Buttons befinden.
Ich habe die insgesamt 110 Buttons in einem Panel mithilfe des GridLayouts zu einer schönen Tabelle angeordnet. Nun möchte ich aber bei einem einzelnen Button das Bildchen verändern, und zwar mit setIcon.

Meine bisherigen Versuche (ich bin Anfänger) sind fehlgeschalgen. Ich habe schlicht versucht, den Button zu verändern und ihn dann erneut mit panel.add() zu aktualisieren. Auf den ersten Blick war das zwar erfolgreich, minimiert man jedoch den Frame und ruft ihn erneut auf, erscheint der Button zusaätzlich am unteren Rand. Hier zur Verdeutlichung der QT:
Die betroffene Methode ist changeIcon();

Java:
public User_Interface () 
	{
		frame.setBounds(0, 0, 1020, 480);
		frame.setLayout(new FlowLayout(FlowLayout.CENTER, 40, 0));
		mypanel = User_Interface.setPanel(mypanel, Barray, false);
		mypanel.setPreferredSize(dim);
		cpupanel = User_Interface.setPanel(cpupanel, Barray, true);	
		cpupanel.setPreferredSize(dim);
		frame.add(mypanel);
		frame.add(cpupanel);
		frame.setVisible(true);
	}
	public static JPanel setPanel (JPanel panel, JButton[][] Barray, boolean cpu)
	{
		if (cpu==false)
			panel.setBounds(0, 0, 440, 440);
		else
			panel.setBounds(580, 0, 440, 440);
		
		Barray = User_Interface.initButtons(Barray,false);
		Barray = User_Interface.initButtons(Barray, true);
		for (int i=0; i<=9; i++)
		{
			for (int j=0; j<=9; j++)
				panel.add(Barray[i][j]);
		}
		panel.setLayout(new GridLayout(11,10,0,0));
		return panel;
	}
	public static JButton[][] initButtons (JButton[][] Barray, boolean cpu)
	{
		for (int i=0; i<=9; i++)
		{
			for (int j=0; j<=9; j++)
			{
				Barray[i][j]= new JButton (User_Interface.loadImage("water"));
				if (cpu==false)
					Barray[i][j].setBounds(40+40*i,40+40*j,40,40);
				else
					Barray[i][j].setBounds(580+40*i, 580+40*j,40,40);
			}
		}
		return Barray;
	}
	public void changeIcon (boolean cpu, String name, int x, int y)
	{
		Barray[x][y].setIcon(User_Interface.loadImage(name));
		mypanel.add(Barray[x][y]);
	}
}

Vielen Dank im Voraus,
Ardam
 
Versuch mal sowas:

Java:
public void changeIcon (boolean cpu, String name, int x, int y)
    {
        Barray[x][y].setIcon(User_Interface.loadImage(name));    // Das Icon des Buttons aktualisieren

        // mypanel.revalidate();
        mypanel.repaint();           // Das Panel neuzeichnen
    }

Sollte das nicht funktionieren kannst du mal noch die revalidate()-Methode dazu benutzen. Aber da sich nur der Inhalt einer Komponente und nicht deren Größe geändert hat, sollte repaint() reichen?! (bin mir nicht ganz sicher).
 
Hallo m0nk3y,
danke, tatsächlich ändert sich jetzt nach Minimieren und neu aufrufen nicht mehr. Dafür VIELEN DANK!
Zwar wird noch das falsche Panel verändert, aber da werde ich wohl irgendwo die Variablen vertauscht haben 😉

Liebe Grüße, Ardam.
 
Java:
import java.awt.EventQueue;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;

import javax.imageio.ImageIO;
import javax.swing.GroupLayout;
import javax.swing.GroupLayout.ParallelGroup;
import javax.swing.GroupLayout.SequentialGroup;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;


public class ButtonArray extends JFrame
{
	
	private JPanel contentPane;
	private ImageIcon icon;
	
	class ChangeIconActionListener implements ActionListener
	{

		@Override
		public void actionPerformed(ActionEvent e)
		{
			JButton button=(JButton)e.getSource();
			button.setIcon(icon);
		}
		
	}
	
	/**
	 * Launch the application.
	 */
	public static void main(String[] args)
	{
		EventQueue.invokeLater(new Runnable()
			{
				public void run()
				{
					try
					{
						ButtonArray frame = new ButtonArray();
						frame.setVisible(true);
					} catch (Exception e)
					{
						e.printStackTrace();
					}
				}
			});
	}
	
	/**
	 * Create the frame.
	 */
	public ButtonArray()
	{
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setBounds(100, 100, 450, 300);
		contentPane = new JPanel();
		contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
		GroupLayout layout=new GroupLayout(contentPane);
		contentPane.setLayout(layout);
		setContentPane(contentPane);
		
		try
		{
			Image image=ImageIO.read(new URL("http://www.java-forum.org/images/buttons/post_thanks.gif"));
			icon=new ImageIcon(image.getScaledInstance(30,20,Image.SCALE_DEFAULT));
		} catch (MalformedURLException e)
		{
			e.printStackTrace();
		} catch (IOException e)
		{
			e.printStackTrace();
		}
			
		ParallelGroup hGroup=layout.createParallelGroup();
		SequentialGroup vGroup=layout.createSequentialGroup();
		ActionListener listener=new ChangeIconActionListener();
		
		for(int i=0;i<20;i++)
		{
			ParallelGroup vertRow=layout.createParallelGroup();
			SequentialGroup horizRow=layout.createSequentialGroup();
			
			for(int j=0;j<5;j++)
			{
				JButton button=new JButton(String.valueOf(5*i+j));
				button.addActionListener(listener);
				
				horizRow.addComponent(button,100,100,100);
				vertRow.addComponent(button,25,25,25);
			}
			vGroup.addGroup(vertRow);
			hGroup.addGroup(horizRow);
		}
		layout.setVerticalGroup(vGroup);
		layout.setHorizontalGroup(hGroup);
		pack();	
	}
}
 
Tut mir Leid wegen des Doppelpostes, aber ich habe ein weiteres Problem bei der gleichen Klasse.
Wie bereits oben angesprochen, wird das falsche Feld verändert. Egal, was ich schreibe (ob mypanel.repaint() oder cpupanel.repaint() ), es wird immer nur das cpupanel aktualisiert. Habt ihr diesbezüglich Ideen?
Code ist ja oben 😉

Wieder Danke im Voraus, Ardam
 
Nein, validate() brachte nicht den erwünschten Erfolg...

Vielleicht gibt es Probleme, weil ich für beide Panels das selbe Button-Array "Barray" verwende?
 
Brauchst du auch alles nicht. Checkliste:
  • Buttons werden nur einmal beim erstellen des Panels geaddet
  • Icon ist nicht null
  • Dem Panel das gewünschte Layout geben BEVOR du Komponenten addest
Edit: und ja, ein Button kann immer nur auf einem Panel liegen. Wenn du ihn zu einem anderen Panel addest gibts Probleme.
 

Zurück
Oben