AWT eigenem Knopf ActionListener zuweisen

derSoerrn

Aktives Mitglied
Hallo zusammen,

ich hab eine eigene Knopfklasse geschrieben, bei welcher man drei Bilder und die Position angibt und dann ein Knopf erstellt wird, der wie die JButtons aus Swing dann sein Aussehen ändert:

Bild 1: normales Aussehen
Bild 2: Wenn Fokus
Bild 3: Wenn Maus gedrückt

Das Problem, was ich nun habe ist, dass ich nicht weiß, wie ich der Klasse bzw. dem Knopf sagen soll, dass er auf einen ActionListener "hören" soll.

Ich habe es zuerst mit einem MouseListner versucht, der dann bei einem Mausklick den gewünschten Effekt ausführt. Jedoch funktioniert diese Möglichkeit nicht auf den Bildern, sonder nur am Rand, da die Bilder den Mausklick anscheinend nicht "durchlassen".

Ich hoffe Ihr könnt mir helfen.

LG
 
kommt drauf an, wie du die Bilder deiner ButtonKlasse addest?!
erbt die Klasse von JButton, JPanel, JComponent...und wem addest du den MouseListener...Code würde hier helfen 😉 am besten in Form eines KSKB
 
Java:
import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.ActionListener;

import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class JPictureButton extends JPanel{
    JLabel knopf;
    Icon bild1, bild2, bild3;
    String aufschrift;
    private int x, y, width, height;
    public JPictureButton(int x, int y, int width, int height, String pfad1, String pfad2, String pfad3){
        this.x = x;
        this.y = y;
        this.width = width;
        this.height = height;
        this.bild1 = new ImageIcon(getClass().getResource(pfad1));
        this.bild2 = new ImageIcon(getClass().getResource(pfad2));
        this.bild3 = new ImageIcon(getClass().getResource(pfad3));
        this.setBounds(x, y, width, height);
        this.setLayout(new FlowLayout());
        knopf = new JLabel();
        knopf.setIcon(bild1);
        knopf.addMouseListener(new ChangeIcon());
        add(knopf);
    }

    public JPictureButton(int x, int y, int width, int height, String pfad1, String pfad2, String pfad3, String aufschrift){
        this.x = x;
        this.y = y;
        this.width = width;
        this.height = height;
        this.bild1 = new ImageIcon(getClass().getResource(pfad1));
        this.bild2 = new ImageIcon(getClass().getResource(pfad2));
        this.bild3 = new ImageIcon(getClass().getResource(pfad3));
        this.aufschrift = aufschrift;
        knopf = new JLabel();
        knopf.setLayout(new FlowLayout());
        knopf.setIcon(bild1);
        knopf.setText(aufschrift);
        knopf.setBounds(x, y, width, height);
        knopf.setFont(new Font("Arial", Font.BOLD, 30)) ;
        knopf.setForeground(Color.BLACK);
        knopf.setIconTextGap(-200);
        knopf.addMouseListener(new ChangeIcon());
        add(knopf);
    }

    public void setzeSchrift(String text, String schriftname, int art, int groesse, Color farbe){
        knopf.setText(text);
        knopf.setFont(new Font(schriftname, art, groesse));
        knopf.setForeground(farbe);
        knopf.setIconTextGap(-200);
    }

    @Override
    public void addMouseListener(MouseListener m){
        super.addMouseListener(m);
        knopf.addMouseListener(m);
    }

    @Override
    public void removeMouseListener(MouseListener m){
        super.removeMouseListener(m);
        knopf.removeMouseListener(m);
    }

    private class ChangeIcon implements MouseListener{

        private boolean geklickt = false;
        private boolean verlassen = false;

        @Override
        public void mouseClicked(MouseEvent e) {

        }

        @Override
        public void mouseEntered(MouseEvent e) {
            knopf.setIcon(bild2);
            verlassen = false;
        }

        @Override
        public void mouseExited(MouseEvent e) {
            if(!geklickt){
                knopf.setIcon(bild1);
                knopf.setIconTextGap(-200);
            }
            verlassen = true;
        }

        @Override
        public void mousePressed(MouseEvent e) {
            knopf.setIcon(bild3);
            geklickt = true;
        }

        @Override
        public void mouseReleased(MouseEvent e) {
            knopf.setIcon(bild2);
            geklickt = false;
            if(verlassen){
                knopf.setIcon(bild1);
            }
        }
    }
}

Also hier ist schonmal der Code. Ich erbe von JPanel, erzeuge auf diesem ein Label, was das Bild ändert. Aber das seht Ihr ja vermutlich selbst 😛

P.S. bin seit gerade eben hier und wusste nicht genau wohin mit dem Thema, darum sorry falls es hier falsch ist ...
 
mmh, und was soll nicht funktionieren?

hiermal dein Bsp-Code in einem KSKB und unten als runnable Jar (mit Bildern)...

Java:
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;

import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class JPictureButton extends JPanel {
	JLabel knopf;
	Icon bild1, bild2, bild3;
	String aufschrift;
	private int x, y, width, height;

	public static void main(String[] args) {
		JFrame f = new JFrame();
		f.setSize(600, 600);
		f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		f.setLocationRelativeTo(null);
		f.add(new JPictureButton(0, 0, 500, 500, "/pic1.jpg", "pic2.jpg",
				"pic3.jpg", "Hallo"));
		f.setVisible(true);
	}

	public JPictureButton(int x, int y, int width, int height, String pfad1,
			String pfad2, String pfad3) {
		this.x = x;
		this.y = y;
		this.width = width;
		this.height = height;
		this.bild1 = new ImageIcon(getClass().getResource(pfad1));
		this.bild2 = new ImageIcon(getClass().getResource(pfad2));
		this.bild3 = new ImageIcon(getClass().getResource(pfad3));
		this.setBounds(x, y, width, height);
		this.setLayout(new FlowLayout());
		knopf = new JLabel();
		knopf.setIcon(bild1);
		knopf.addMouseListener(new ChangeIcon());
		add(knopf);
	}

	public JPictureButton(int x, int y, int width, int height, String pfad1,
			String pfad2, String pfad3, String aufschrift) {
		this.x = x;
		this.y = y;
		this.width = width;
		this.height = height;
		this.bild1 = new ImageIcon(getClass().getResource(pfad1));
		this.bild2 = new ImageIcon(getClass().getResource(pfad2));
		this.bild3 = new ImageIcon(getClass().getResource(pfad3));
		this.aufschrift = aufschrift;
		knopf = new JLabel();
		knopf.setLayout(new FlowLayout());
		knopf.setIcon(bild1);
		knopf.setText(aufschrift);
		knopf.setBounds(x, y, width, height);
		knopf.setFont(new Font("Arial", Font.BOLD, 30));
		knopf.setForeground(Color.BLACK);
		knopf.setIconTextGap(-200);
		knopf.addMouseListener(new ChangeIcon());
		add(knopf);
	}

	public void setzeSchrift(String text, String schriftname, int art,
			int groesse, Color farbe) {
		knopf.setText(text);
		knopf.setFont(new Font(schriftname, art, groesse));
		knopf.setForeground(farbe);
		knopf.setIconTextGap(-200);
	}

	@Override
	public void addMouseListener(MouseListener m) {
		super.addMouseListener(m);
		knopf.addMouseListener(m);
	}

	@Override
	public void removeMouseListener(MouseListener m) {
		super.removeMouseListener(m);
		knopf.removeMouseListener(m);
	}

	private class ChangeIcon implements MouseListener {

		private boolean geklickt = false;
		private boolean verlassen = false;

		@Override
		public void mouseClicked(MouseEvent e) {
			// na wenn hier nichts steht...gibt es halt kein Klickevent, außer
			// wenn die Mouse gedrückt wird...
		}

		@Override
		public void mouseEntered(MouseEvent e) {
			knopf.setIcon(bild2);
			verlassen = false;
		}

		@Override
		public void mouseExited(MouseEvent e) {
			if (!geklickt) {
				knopf.setIcon(bild1);
				knopf.setIconTextGap(-200);
			}
			verlassen = true;
		}

		@Override
		public void mousePressed(MouseEvent e) {
			knopf.setIcon(bild3);
			geklickt = true;
		}

		@Override
		public void mouseReleased(MouseEvent e) {
			knopf.setIcon(bild2);
			geklickt = false;
			if (verlassen) {
				knopf.setIcon(bild1);
			}
		}
	}
}
 

Anhänge

Zeile 77-86 kann übrigens weg wenn nur das JLabel den Listener bekommt,
das ganze umgebende JPanel könnte wegfallen, ein JLabel reicht,

x, y, width, height haben derzeit keine Funktion, setBounds() ist nur für null-Layout interessant,
welches du lieber gar nicht erst näher kennenlernen solltest,
die Breite und Höhe könnte man wenn überhaupt besser aus den Bildern auslesen statt redundant zu übergeben, woher kennt der Aufrufer sie?

knopf als JLabel braucht im Moment kein Layout,

die beiden Konstruktoren solltest du zusammenfassen, also der eine ruft den anderen auf mit aufschrift==null,
mit if unterscheiden, ob der zugehörige Code wie Schrift-Setzen dann ausgeführt wird oder nicht
 
Wenn ich den Knopf jetzt in einer anderen Klasse initialisiere und dann in der Klasse mit einem MouseListener arbeite funktioniert es nicht. Ich hab das nämlich eigentlich so geschrieben, dass ich diesen Knopf in meinem GUI benutzen kann. Ich fände das eher unpraktisch wenn ich diesen knopf jetzt immer für jedes "Ereignis" speziell anpassen muss. Verstehst du?
 
extern mit deinen überschriebenen Methoden einen zweiten MouseListener hinzuzufügen funktioniert genauso,
weiterhin kein Problem zu erkennen,
bei einem einfachen JLabel ohne JPanel sicher genauso, siehe mein Post zwischendurch, falls übersehen

du könntest auch das einfachere ActionListener-Modell manuell nachbauen:
nach außen set/addActionListener() anbieten, intern eine Liste oder eine einzelne Variable dafür,
der vorhandene MouseListener ruft beim Klick die actionPerformed()-Methode des gesetzen Listeners auf

ActionEvent wenn nötig ist auch nachzubauen, vielleicht geht es aber ohne, also null
 
Zuletzt bearbeitet von einem Moderator:
Hab mal den Code ausprobiert und kann hier keinen Unterschied zu einem normalen JButton feststellen, ausser, dass hier die Border fehlt und kein Fokus angezeigt wird.
Wenn man das völlig losgelöst behandeln will würde ich mich SlaterB's Vorschlag anschließen und die addActionLister() und das auslösen des Events selbst implementieren
 
Ich hab' das jetzt mal so umgeschrieben, sodass ich statt des JPanel vom JButton (JLabel ist jetzt komplett weg) erbe, jedoch habe ich jetzt einen Rahmen um den Knopf. Wenn ihr mir noch sagen könntet wie ich diesen weg bekomme, dann seit ihr echt die besten 😛

Hab Euch ein Bild angeheftet auf dem man den Rahmen sieht. "setOpaque" hat übrings nicht funktioniert...

LG
 

Anhänge

  • Rahmen.png
    Rahmen.png
    1,5 KB · Aufrufe: 53
Kann man den Button nicht auch irgendwie ganz durchsichtig machen? Ich benutze nämlich (leider) abgerundete Bilder für mein GUI. Sonst ging
Code:
setBorder(null)
 
Tut mir Leid, hab vergessen es zu schreiben 😛

hab das benutzt: "this.setContentAreaFilled(false);"

Aber wisst ihr, ob es "Schiebeknöpfe" in Java gibt? Ich hab gerade mal im API geguckt und nichts gefunden. Anbei sollte ein Bild von einem Knopf sein, wie ich ihn mir vorstelle.
 

Anhänge

  • Schiebeknopf.PNG
    Schiebeknopf.PNG
    4,4 KB · Aufrufe: 32
eine GUI-Komponente in einem bestimmten eigenen Design, auch nur rund statt eckig,
das ist wahrlich bereits außerhalb des normal bekannten Anfänger-Standards,

vielleicht findest du einen passenden Look & Feel (Konfiguration der Darstellung),
vielleicht kannst du einen derartigen modifizieren (ich nicht),
oder du baust wieder einmal etwas selber, wohl weniger mit Bildern hier, mehr mit paint-Methoden

meinst du denn überhaupt diese Komponente oder willst nur zwischen A und B hin und her schalten? das wäre Checkbox/ RadioButton
 
Ich bräuchte diesen Knopf für das Einstellungsmenü, um bestimmte Einstellungen eben ein oder auszuschalten und dafür fände ich diesen Knopf wohl am besten. Ich könnte da natürlich auch eine/n CheckBox/RadioButton benutzen, aber das ist meiner Meinung nach hässlich 😛

Ich werde dann wohl mal deinen letzten Vorschlag ausprobieren ;-)
 
wenn nur A/B, dann geht ja auch Bilder, kein Schieben Pixel um Pixel,
mit mousePressed() usw. sicher machbar
 
Im Prinzip ist das m.M. auch wieder eine Standardkomponente:
JToggleButton, dem man zwei Icons zuweist (setIcon & setSelectedIcon), Border,Fokus, Hintergrund, kann man ja wieder ausblenden.
 

Neue Themen


Zurück
Oben