Habe eine Bilderschau soweit fertig, jetzt fehlt mir noch eine Kleinigkeit.
Habe es soweit hinbekommen, das ein Bild skaliert wird wenn der haken sitzt, leider ist ein bereits ausgewähltes Bild nicht möglich. Ich möchte aber das auch ein bereits angezeigtes Bild durch anklicken der JCheckbox noch geändert wird. Hat vielleicht jemand einen Tip. Habe bereits soweit ich meine alles vorbereitet Listener für die Checkbox.
Code einfach mal ansehen. ???:L
[Java]
package bildbetrachter;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.io.File;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
import javax.swing.JTextField;
import javax.swing.JSpinner;
import javax.swing.SpinnerNumberModel;
public class Bildbetrachter extends JFrame{
//automatisch über Eclipse ergänzt
private static final long serialVersionUID = 5926848670766709720L;
//für die Schaltflächen
private JButton oeffnen, beenden, oeffnenSchau, beendenSchau;
//für die Eingabe
private JTextField eingabe;
//für die Anzeige
private BildPanel bildAnzeige, bildAnzeigeSchau;
//für die Anpassung
private JCheckBox skalieren;
// Drehfeld für die Zeitspanne
private JSpinner zeitschalter;
// Variable für die Anzeigendauer
private int anzeigenDauer;
// Variable für den Wert im Spinner
private int sekunden;
//die innere Klasse mit dem Listener
class MeinListener implements ActionListener, ChangeListener,ItemListener {
@Override
public void actionPerformed(ActionEvent e) {
//für die Schaltflächen zum Beenden
if (e.getActionCommand().equals("Ende"))
System.exit(0);
//für die Auswahl eines einzelnen Bildes
if (e.getActionCommand().equals("Laden"))
bildLaden();
//für die Auswahl der Bilder für die Bilderschau
if (e.getActionCommand().equals("LadenSchau"))
bilderSchau();
// Grundeinstellung Sekundenanzeige des Drehfeldes
sekunden = 5;
//Grundeinstellung für die Pause bei der Bilderschau in Millisekunden
anzeigenDauer = 1000 * sekunden;}
// Reaktion auf Statuswechsel in dem Drehfeld
// Abfrage des Spinnerwertes und Ändern der Anzeigendauer
@Override
public void stateChanged(ChangeEvent e) {
if (e.getSource()instanceof JSpinner){
int sekunden = (Integer) zeitschalter.getValue();
anzeigenDauer = 1000 * sekunden;
}
}
// Änderung an der JCheckbox feststellen und reagieren
// Bild sofort skalieren
@Override
public void itemStateChanged(ItemEvent e) {
if (e.getSource()instanceof JCheckBox)
;
}
}
//der Konstruktor
public Bildbetrachter(String titel) {
super(titel);
initGUI();
}
//die Methode zum Erstellen der Oberfläche
private void initGUI() {
//die Panels für die Register
JPanel registerEinzel = new JPanel();
JPanel registerSchau = new JPanel();
//das TabbedPane
JTabbedPane panelKomplett = new JTabbedPane();
//das Register für die Einzelanzeige
//eine neue Instanz für das Panel mit der Grafik erzeugen
bildAnzeige = new BildPanel();
//die Komponenten erstellen und einbauen
registerEinzel.setLayout(new FlowLayout(FlowLayout.LEFT));
registerEinzel.add(bildAnzeige);
oeffnen = new JButton("Bild laden");
beenden = new JButton("Beenden");
oeffnen.setActionCommand("Laden");
beenden.setActionCommand("Ende");
eingabe = new JTextField(20);
skalieren = new JCheckBox("Anpassen");
registerEinzel.add(new JLabel("Bilddatei: "));
registerEinzel.add(eingabe);
registerEinzel.add(skalieren);
registerEinzel.add(oeffnen);
registerEinzel.add(beenden);
//die Listener verbinden
MeinListener listener = new MeinListener();
oeffnen.addActionListener(listener);
beenden.addActionListener(listener);
skalieren.addItemListener(listener);
//das Register für die Bilderschau
//eine neue Instanz für das Panel mit der Grafik erzeugen
bildAnzeigeSchau = new BildPanel();
//die Komponenten erstellen und einbauen
registerSchau.setLayout(new FlowLayout(FlowLayout.LEFT));
registerSchau.add(bildAnzeigeSchau);
oeffnenSchau = new JButton("Bilder laden");
beendenSchau = new JButton("Beenden");
oeffnenSchau.setActionCommand("LadenSchau");
// Variable setzen für zeitschalter Drehfeld
SpinnerNumberModel drehFeldModel = new SpinnerNumberModel(5,0,10,1);
zeitschalter = new JSpinner(drehFeldModel);
//die Schaltfläche zum Beenden bekommt dasselbe ActionCommand wie im anderen Register
beendenSchau.setActionCommand("Ende");
registerSchau.add(oeffnenSchau);
registerSchau.add(beendenSchau);
registerSchau.add(zeitschalter);
//die Listener verbinden
oeffnenSchau.addActionListener(listener);
beendenSchau.addActionListener(listener);
zeitschalter.addChangeListener(listener);
//und nun alles zusammenbauen
panelKomplett.add("Einzelbild",registerEinzel);
panelKomplett.add("Bilderschau",registerSchau);
add(panelKomplett);
//Größe setzen, anzeigen, keine Größenänderungen zulassen und Standard-Verhalten festlegen
setSize(350,450);
setResizable(false);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
}
//die Methode zum Laden eines Bildes über den Dialog
private void bildLaden() {
//einen Standard-Öffnen-Dialog erzeugen
BildbetrachterDialog dialog = new BildbetrachterDialog();
//die Rückgabe holen
String datei = dialog.dialogZeigen();
//wenn eine Datei ausgewählt wurde, laden
if (datei != null) {
bildAnzeige.grafikLaden(datei, skalieren.isSelected());
//den Namen der Datei im Eingabefeld anzeigen
eingabe.setText(datei);
}
}
//die Methode zur Anzeige der Bilderschau
private void bilderSchau() {
//einen Standard-Öffnen-Dialog erzeugen
BildbetrachterDialog dialogSchau = new BildbetrachterDialog();
//die Rückgabe holen und in einem Array vom Typ File ablegen
File[] dateien = dialogSchau.dialogZeigenMehrere();
//wenn eine Datei ausgewählt wurde, alle Dateien nacheinander anzeigen
if (dateien != null) {
for (File datei: dateien) {
bildAnzeigeSchau.grafikLaden(datei.toString(), true);
//nach jeder Datei machen wir eine kurze Pause
// Wert wird über JSpinner gesetzt
try {
Thread.sleep(anzeigenDauer);
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
[/Java]
und hier das AnzeigePanel
[Java]
package bildbetrachter;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.border.BevelBorder;
//die Klasse erzeugt ein Panel, in das eine Grafik geladen werden kann
public class BildPanel extends JPanel{
//automatisch über Eclipse ergänzt
private static final long serialVersionUID = 7482508662820162216L;
//für das Bild
private BufferedImage bild;
//für die Änderungen beim Skalieren
private double neueBildBreite;
private double neueBildHoehe;
//der Konstruktor
//er setzt die Größe, zeichnet einen Rahmen
//und beschafft den Grafik-Kontext
public BildPanel() {
setPreferredSize(new Dimension(300,300));
setBorder(new BevelBorder(BevelBorder.LOWERED));
}
//die Methode zum Laden der Grafik
//der Name der Datei wird als Zeichenkette übergeben
//skaliert steuert, ob die Bildgröße angepasst wird oder nicht
public void grafikLaden(String datei, boolean skaliert) {
//eine lokale Variable für die Änderung der Proportionen
double proportion;
//die Ausnahmebehandlung ist zwingend erforderlich
try {
bild = ImageIO.read(new File(datei));
//soll das Bild angepasst werden?
if (skaliert == true) {
//ist das Bild höher als breit?
if (bild.getHeight() > bild.getWidth())
//dann ermitteln wir die optimale neue Höhe
proportion = (double) this.getSize().height / bild.getHeight();
else
//sonst die optimale neue Breite
proportion = (double) this.getSize().width / bild.getWidth();
}
else
//wenn nicht, bleibt die Proportion unverändert
proportion = 1.0;
//die "neue" Breite und Höhe berechnen
//die Variablen müssen als Instanzvariablen vom Typ double vereinbart werden
neueBildBreite = proportion * bild.getWidth();
neueBildHoehe = proportion * bild.getHeight();
//den Grafik-Kontext beschaffen
Graphics grafikKontext = this.getGraphics();
//die Anzeige löschen
grafikKontext.clearRect(0, 0, this.getSize().width, this.getSize().height);
//das Bild anzeigen
//dabei wird die neue Höhe und Breite berücksichtigt
grafikKontext.drawImage(bild, 0, 0, (int) neueBildBreite, (int) neueBildHoehe, this);
}
catch (IOException e) {
JOptionPane.showMessageDialog(this.getParent(), "Beim Laden hat es ein Problem gegeben", "Fehler", JOptionPane.ERROR_MESSAGE);
}
}
//die Methode zum Neuzeichnen überschreiben, damit die Bilder nicht verschwinden
@Override
protected void paintComponent(Graphics g) {
//die Methode zum Neuzeichnen der übergeordneten Klasse aufrufen, damit es keine Probleme gibt
super.paintComponent(g);
//wenn ein Bild angezeigt wurde, neu zeichnen lassen
if (bild != null)
g.drawImage(bild, 0, 0, (int) neueBildBreite, (int) neueBildHoehe, this);
}
}
[/Java]
Vielen Dank
Habe es soweit hinbekommen, das ein Bild skaliert wird wenn der haken sitzt, leider ist ein bereits ausgewähltes Bild nicht möglich. Ich möchte aber das auch ein bereits angezeigtes Bild durch anklicken der JCheckbox noch geändert wird. Hat vielleicht jemand einen Tip. Habe bereits soweit ich meine alles vorbereitet Listener für die Checkbox.
Code einfach mal ansehen. ???:L
[Java]
package bildbetrachter;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.io.File;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
import javax.swing.JTextField;
import javax.swing.JSpinner;
import javax.swing.SpinnerNumberModel;
public class Bildbetrachter extends JFrame{
//automatisch über Eclipse ergänzt
private static final long serialVersionUID = 5926848670766709720L;
//für die Schaltflächen
private JButton oeffnen, beenden, oeffnenSchau, beendenSchau;
//für die Eingabe
private JTextField eingabe;
//für die Anzeige
private BildPanel bildAnzeige, bildAnzeigeSchau;
//für die Anpassung
private JCheckBox skalieren;
// Drehfeld für die Zeitspanne
private JSpinner zeitschalter;
// Variable für die Anzeigendauer
private int anzeigenDauer;
// Variable für den Wert im Spinner
private int sekunden;
//die innere Klasse mit dem Listener
class MeinListener implements ActionListener, ChangeListener,ItemListener {
@Override
public void actionPerformed(ActionEvent e) {
//für die Schaltflächen zum Beenden
if (e.getActionCommand().equals("Ende"))
System.exit(0);
//für die Auswahl eines einzelnen Bildes
if (e.getActionCommand().equals("Laden"))
bildLaden();
//für die Auswahl der Bilder für die Bilderschau
if (e.getActionCommand().equals("LadenSchau"))
bilderSchau();
// Grundeinstellung Sekundenanzeige des Drehfeldes
sekunden = 5;
//Grundeinstellung für die Pause bei der Bilderschau in Millisekunden
anzeigenDauer = 1000 * sekunden;}
// Reaktion auf Statuswechsel in dem Drehfeld
// Abfrage des Spinnerwertes und Ändern der Anzeigendauer
@Override
public void stateChanged(ChangeEvent e) {
if (e.getSource()instanceof JSpinner){
int sekunden = (Integer) zeitschalter.getValue();
anzeigenDauer = 1000 * sekunden;
}
}
// Änderung an der JCheckbox feststellen und reagieren
// Bild sofort skalieren
@Override
public void itemStateChanged(ItemEvent e) {
if (e.getSource()instanceof JCheckBox)
;
}
}
//der Konstruktor
public Bildbetrachter(String titel) {
super(titel);
initGUI();
}
//die Methode zum Erstellen der Oberfläche
private void initGUI() {
//die Panels für die Register
JPanel registerEinzel = new JPanel();
JPanel registerSchau = new JPanel();
//das TabbedPane
JTabbedPane panelKomplett = new JTabbedPane();
//das Register für die Einzelanzeige
//eine neue Instanz für das Panel mit der Grafik erzeugen
bildAnzeige = new BildPanel();
//die Komponenten erstellen und einbauen
registerEinzel.setLayout(new FlowLayout(FlowLayout.LEFT));
registerEinzel.add(bildAnzeige);
oeffnen = new JButton("Bild laden");
beenden = new JButton("Beenden");
oeffnen.setActionCommand("Laden");
beenden.setActionCommand("Ende");
eingabe = new JTextField(20);
skalieren = new JCheckBox("Anpassen");
registerEinzel.add(new JLabel("Bilddatei: "));
registerEinzel.add(eingabe);
registerEinzel.add(skalieren);
registerEinzel.add(oeffnen);
registerEinzel.add(beenden);
//die Listener verbinden
MeinListener listener = new MeinListener();
oeffnen.addActionListener(listener);
beenden.addActionListener(listener);
skalieren.addItemListener(listener);
//das Register für die Bilderschau
//eine neue Instanz für das Panel mit der Grafik erzeugen
bildAnzeigeSchau = new BildPanel();
//die Komponenten erstellen und einbauen
registerSchau.setLayout(new FlowLayout(FlowLayout.LEFT));
registerSchau.add(bildAnzeigeSchau);
oeffnenSchau = new JButton("Bilder laden");
beendenSchau = new JButton("Beenden");
oeffnenSchau.setActionCommand("LadenSchau");
// Variable setzen für zeitschalter Drehfeld
SpinnerNumberModel drehFeldModel = new SpinnerNumberModel(5,0,10,1);
zeitschalter = new JSpinner(drehFeldModel);
//die Schaltfläche zum Beenden bekommt dasselbe ActionCommand wie im anderen Register
beendenSchau.setActionCommand("Ende");
registerSchau.add(oeffnenSchau);
registerSchau.add(beendenSchau);
registerSchau.add(zeitschalter);
//die Listener verbinden
oeffnenSchau.addActionListener(listener);
beendenSchau.addActionListener(listener);
zeitschalter.addChangeListener(listener);
//und nun alles zusammenbauen
panelKomplett.add("Einzelbild",registerEinzel);
panelKomplett.add("Bilderschau",registerSchau);
add(panelKomplett);
//Größe setzen, anzeigen, keine Größenänderungen zulassen und Standard-Verhalten festlegen
setSize(350,450);
setResizable(false);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
}
//die Methode zum Laden eines Bildes über den Dialog
private void bildLaden() {
//einen Standard-Öffnen-Dialog erzeugen
BildbetrachterDialog dialog = new BildbetrachterDialog();
//die Rückgabe holen
String datei = dialog.dialogZeigen();
//wenn eine Datei ausgewählt wurde, laden
if (datei != null) {
bildAnzeige.grafikLaden(datei, skalieren.isSelected());
//den Namen der Datei im Eingabefeld anzeigen
eingabe.setText(datei);
}
}
//die Methode zur Anzeige der Bilderschau
private void bilderSchau() {
//einen Standard-Öffnen-Dialog erzeugen
BildbetrachterDialog dialogSchau = new BildbetrachterDialog();
//die Rückgabe holen und in einem Array vom Typ File ablegen
File[] dateien = dialogSchau.dialogZeigenMehrere();
//wenn eine Datei ausgewählt wurde, alle Dateien nacheinander anzeigen
if (dateien != null) {
for (File datei: dateien) {
bildAnzeigeSchau.grafikLaden(datei.toString(), true);
//nach jeder Datei machen wir eine kurze Pause
// Wert wird über JSpinner gesetzt
try {
Thread.sleep(anzeigenDauer);
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
[/Java]
und hier das AnzeigePanel
[Java]
package bildbetrachter;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.border.BevelBorder;
//die Klasse erzeugt ein Panel, in das eine Grafik geladen werden kann
public class BildPanel extends JPanel{
//automatisch über Eclipse ergänzt
private static final long serialVersionUID = 7482508662820162216L;
//für das Bild
private BufferedImage bild;
//für die Änderungen beim Skalieren
private double neueBildBreite;
private double neueBildHoehe;
//der Konstruktor
//er setzt die Größe, zeichnet einen Rahmen
//und beschafft den Grafik-Kontext
public BildPanel() {
setPreferredSize(new Dimension(300,300));
setBorder(new BevelBorder(BevelBorder.LOWERED));
}
//die Methode zum Laden der Grafik
//der Name der Datei wird als Zeichenkette übergeben
//skaliert steuert, ob die Bildgröße angepasst wird oder nicht
public void grafikLaden(String datei, boolean skaliert) {
//eine lokale Variable für die Änderung der Proportionen
double proportion;
//die Ausnahmebehandlung ist zwingend erforderlich
try {
bild = ImageIO.read(new File(datei));
//soll das Bild angepasst werden?
if (skaliert == true) {
//ist das Bild höher als breit?
if (bild.getHeight() > bild.getWidth())
//dann ermitteln wir die optimale neue Höhe
proportion = (double) this.getSize().height / bild.getHeight();
else
//sonst die optimale neue Breite
proportion = (double) this.getSize().width / bild.getWidth();
}
else
//wenn nicht, bleibt die Proportion unverändert
proportion = 1.0;
//die "neue" Breite und Höhe berechnen
//die Variablen müssen als Instanzvariablen vom Typ double vereinbart werden
neueBildBreite = proportion * bild.getWidth();
neueBildHoehe = proportion * bild.getHeight();
//den Grafik-Kontext beschaffen
Graphics grafikKontext = this.getGraphics();
//die Anzeige löschen
grafikKontext.clearRect(0, 0, this.getSize().width, this.getSize().height);
//das Bild anzeigen
//dabei wird die neue Höhe und Breite berücksichtigt
grafikKontext.drawImage(bild, 0, 0, (int) neueBildBreite, (int) neueBildHoehe, this);
}
catch (IOException e) {
JOptionPane.showMessageDialog(this.getParent(), "Beim Laden hat es ein Problem gegeben", "Fehler", JOptionPane.ERROR_MESSAGE);
}
}
//die Methode zum Neuzeichnen überschreiben, damit die Bilder nicht verschwinden
@Override
protected void paintComponent(Graphics g) {
//die Methode zum Neuzeichnen der übergeordneten Klasse aufrufen, damit es keine Probleme gibt
super.paintComponent(g);
//wenn ein Bild angezeigt wurde, neu zeichnen lassen
if (bild != null)
g.drawImage(bild, 0, 0, (int) neueBildBreite, (int) neueBildHoehe, this);
}
}
[/Java]
Vielen Dank