Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Visuelle Styles in Java (https://www.delphipraxis.net/72825-visuelle-styles-java.html)

3_of_8 7. Jul 2006 14:37


Visuelle Styles in Java
 
Morgen.

Ich bastle grade an einer GUI für meinen Java SudokuSolver, die letzte Aufgabe an der Uni für dieses Semester (jedenfalls für mich).

Dabei ist mir aufgefallen, dass ich (ich entwickle unter Windows) immer die langweiligen Buttons im Windows Style habe. Bei den Demos des JDKs und bei dem Beispielprogramm meines Dozenten sehen die Buttons allerdings anders aus, im Java Style eben.

Ich habe mit Look and Feel Zeugs rumexperimentiert, aber nichts hat sich geändert.

Seltsam ist auch, dass das Popupmenü zum Beispiel im Java Style ist, nicht im Windows Style.
Im FileChooser sind die Buttons auch im Java Style.

Woran liegt das? Kann es sein, dass das daran liegt, dass ich es unter Windows teste?

Chewie 8. Jul 2006 00:21

Re: Visuelle Styles in Java
 
Look and Feel ist das richtige Stichwort. Mit UIManager.setLookAndFell() kannst du ein entsprechendes Look And Feel auswählen.

3_of_8 8. Jul 2006 08:11

Re: Visuelle Styles in Java
 
Das hat eben nix gebracht.

Chewie 8. Jul 2006 10:28

Re: Visuelle Styles in Java
 
Welche Controls benutzt du? Die Standard-Swing-Controls sollten sich alle stylen lassen. Wenn sie das nicht machen, dann dürftest du etwas falsch gemacht haben.

Zeig mal ein bisschen Code.

3_of_8 8. Jul 2006 10:51

Re: Visuelle Styles in Java
 
Liste der Anhänge anzeigen (Anzahl: 1)
So siehts aus (egal ob mit oder ohne UIManager.SetLookAndFeel).

Die Komponenten, die gestylt werden sollen sind ausschließlich JButtons, JPanels, JFrames. Und: Ich habe rausgefunden, welche Look and Feels bei mir installiert sind:
Metal javax.swing.plaf.metal.MetalLookAndFeel
CDE/Motif com.sun.java.swing.plaf.motif.MotifLookAndFeel
Windows com.sun.java.swing.plaf.windows.WindowsLookAndFeel
Windows Classic com.sun.java.swing.plaf.windows.WindowsClassicLook AndFeel

Mein Code sieht so aus:

Code:
package gui;

import javax.swing.ComponentInputMap;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.LookAndFeel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.JFileChooser;

import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.Component;
import java.awt.Container;
import java.awt.Button;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.Dimension;
import java.awt.BorderLayout;
import java.io.FileNotFoundException;
import java.io.IOException;

import sudoku.NotSolvableException;
import sudoku.HelpingState;

public class SudokuGUI extends JFrame {
   
    private static final String LOOK_AND_FEEL_ERROR_MESSAGE =
            "Could not initiate look and feel. Will now "
            + "use default look and feel.";

    private static final String INVALID_FILE_MESSAGE = "Could not read file.";

    private static final String LOAD_DIALOG_CAPTION = "Load sudoku";

    private static final String NO_MORE_SOLVABLE_MESSAGE = "Sudoku no more solvable. "
                                + "Use undo or unset to correct the mistakes.";

    private static final String ERROR_CAPTION = "Error";

    private static final String SOLVED_MESSAGE = "Congratulations! The sudoku is solved.";

    private static final String SOLVED_CAPTION = "Sudoku solved";

    private static final String ALREADY_SOLVED_MESSAGE = "The sudoku is already solved.";

    private static final String ALREADY_SOLVED_CAPTION = "Sudoku already solved";

    private static final String CLOSE_BUTTON_CAPTION = "Close";

    private static final String LOAD_BUTTON_CAPTION = "Load";

    private static final String UNDO_BUTTON_CAPTION = "Undo";

    private static final String FILE_NOT_FOUND_MESSAGE =
            "File %s does not exist.";
   
    private static final String HELP_BUTTON_CAPTION =
            "Help";
   
    private HelpingState s;
    private SudokuBoard board;

    public static void main(String[] args) {
        new SudokuGUI();
    }
   
    public void showMessage(String title, String msg) {
        showMessage(title, msg, JOptionPane.PLAIN_MESSAGE);
    }
   
    public void showMessage(String title, String msg, int type) {
        JOptionPane.showMessageDialog(this, msg, title, type);
    }
   
    public SudokuGUI() {
        s = new HelpingState();
        this.setTitle("Sudoku");
       
        for (UIManager.LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
            System.out.println(info);
        }
       
        addComponentListener(new ComponentListener() {
            public void componentResized(ComponentEvent e) {
                JFrame frame = (JFrame) e.getSource();
                if (frame.getWidth() < 280) {
                    frame.setSize(280, frame.getHeight());
                }
                if (frame.getHeight() < 320) {
                    frame.setSize(frame.getWidth(), 320);
                }
            }           
            public void componentMoved(ComponentEvent e) {}
            public void componentHidden(ComponentEvent e) {}
            public void componentShown(ComponentEvent e) {}
        });
        setMinimumSize(new Dimension(160, 180));
        Container cp = getContentPane();
        setLayout(new BorderLayout(20, 20));
        board = new SudokuBoard();
        board.state = s;
        JPanel panel = new JPanel();
        JPanel buttonPanel = new JPanel();
        cp.add(board, BorderLayout.CENTER);
        cp.add(panel, BorderLayout.SOUTH);
        Button help = new Button(HELP_BUTTON_CAPTION);
        Button undo = new Button(UNDO_BUTTON_CAPTION);
        Button load = new Button(LOAD_BUTTON_CAPTION);
        Button close = new Button(CLOSE_BUTTON_CAPTION);
        panel.setLayout(new FlowLayout(FlowLayout.CENTER, 10, 10));
        panel.add(buttonPanel);
        buttonPanel.setLayout(new GridLayout(1, 4, 20, 20));
        buttonPanel.add(help);
        buttonPanel.add(undo);
        buttonPanel.add(load);
        buttonPanel.add(close);
       
        help.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                try {
                   
                    if (s.isSolution()) {
                        showMessage(ALREADY_SOLVED_CAPTION,
                                ALREADY_SOLVED_MESSAGE);
                        board.repaint();
                        return;
                    }
                   
                    s.getHelp();
                                       
                    if (s.isSolution()) {
                        showMessage(SOLVED_CAPTION,
                                SOLVED_MESSAGE);
                    }
                } catch (NotSolvableException ex) {
                    showMessage(ERROR_CAPTION, NO_MORE_SOLVABLE_MESSAGE,
                            JOptionPane.ERROR_MESSAGE);
                }
                board.repaint();
            }
        });
       
        undo.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                s.undo();
                board.repaint();
            }
        });
       
        load.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                JFileChooser fileChooser = new JFileChooser();
                fileChooser.setDialogTitle(LOAD_DIALOG_CAPTION);
                if (fileChooser.showOpenDialog(null) ==
                        JFileChooser.APPROVE_OPTION) {
                    try {
                        s.loadFromFile(fileChooser.getSelectedFile().
                                getAbsolutePath());
                        board.repaint();
                    } catch (FileNotFoundException ex) {
                        showMessage(ERROR_CAPTION,
                                String.format(FILE_NOT_FOUND_MESSAGE,
                                fileChooser.getSelectedFile().getPath()),
                                JOptionPane.ERROR_MESSAGE);
                    } catch (IOException ex) {
                        showMessage(ERROR_CAPTION,
                                INVALID_FILE_MESSAGE,
                                JOptionPane.ERROR_MESSAGE);
                    } catch (NotSolvableException ex) {
                        showMessage(ERROR_CAPTION,
                                "Input file is contradictory or invalid.",
                                JOptionPane.ERROR_MESSAGE);
                    }
                }
            }
        });
       
        close.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                System.exit(0);
            }
        }
        );
       
        setSize(500, 600);
        setVisible(true);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
    }
   
}

Chewie 8. Jul 2006 12:49

Re: Visuelle Styles in Java
 
Zitat:

Zitat von 3_of_8
Code:
    public SudokuGUI() {
        s = new HelpingState();
        this.setTitle("Sudoku");
       
        for (UIManager.LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
            System.out.println(info);
        }
                [color=#ff0000]UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsClassicLookAndFeel");[/color]
       
    }

Also bei mir ändert das das Aussehen, wenn ich den Konstruktor das Look and Feel einstelle. Wenn bei dir nix passiert, vermute ich eher auf ein Problem mit deiner Java-Laufzeitumgebung.

Der_Unwissende 8. Jul 2006 13:00

Re: Visuelle Styles in Java
 
[OT]
Hi, mit 15 an der Uni? Wow, da hat sich wohl was verändert (man wird alt!)

Ich wollte nur kurz was allgemeines zu deinem Code sagen, so richtig hübsch ist der imho nicht. Genau genommen nicht nur imho. Falls du zufällig Eclipse benutzt, dort solltest du ruhig mal alle Warnings (ausser vielleicht die über externalized Strings) anschalten und dich an die halten, dass macht den Code in der Regel echt besser. Ist nicht böse gemeint, sondern wie so oft Konvention und Erfahrung. Gibt da ein echt schönes Buch, The Elements of good Java Style, ist ziemlich günstig zu haben und lässt sich leicht auf andere Sprachen übertragen, kann ich wie immer nur empfehlen.

Hier würde ich dir vorallem dazu raten, mehr Leerzeilen zu verwenden. Zudem solltest du Variablen immer Qualifizieren, Klassenvariablen werden mit einem this.xxxx und wichtiger statische Variablen mit ClassName.xxxx benutzt, das sind auch Warnings in Eclipse (was zeigt, dass es wirklich verbreitet ist und auch einen Sinn hat).

Gruß Der Unwissende
[/OT]

3_of_8 8. Jul 2006 18:08

Re: Visuelle Styles in Java
 
Höa?

Mein Dozent hatte bis jetzt nichts daran zu bekritteln. Dass man immer this.<bezeichner> hernehmen sollte, ist mir neu. Leerzeilen kommen später.

Der_Unwissende 8. Jul 2006 21:03

Re: Visuelle Styles in Java
 
Ist nur guter Codestil, keine Pflicht.
Meine Frage an dich wäre ja jetzt, was spricht gegen ein this? Und für die (nicht unwahrscheinliche) Gegenfrage warum? bleibt hier nur der Verweis darauf, dass es nun einmal Konvention ist. Ist genau wie ein self. in Delphi sauberer, da man sehr leicht lokale Variablen und "globalere" Klassenvariablen unterscheiden kann.
Was ein Dozent bemängelt und was nicht ist, nun ja, nicht so wirklich wichtig. Hatte damals auch sehr verschiedene Tutoren, die Übungen korrigiert haben. Da gab es auch einzelne, da konnte man abgeben was man wollte und andere hatten da sehr viel eingeschränktere Vorstellungen (z.B. wurden 0 Punkte vergeben, wenn einzelne Kommentare fehlten).
Letztlich ist für dich später wichtiger, was dein Arbeitgeber verlangt. Meiner Meinung nach gibt es keine Firma, die möchte dass man auf gar keinen Fall seine Variablen Qualifiziert (wäre auch sinnlos), aber ich kenne einige die eben darauf bestehen.

Insbesondere bei Konstanten hat es auch eine Menge Vorteile. Sagen wir mal du hast folgendes :

Code:
class Klasse1 {
  public static final int IRGENDWAS = 1;
 
  public void doFoo(final int x) {
    if (x == IRGENDWAS) {
      doSomething();
    }

    else {
      doSomethingElse();
    }
  }
}

class Klasse2 {
  public static final int IRGENDWAS = -1;
 
  public void doFoo() {
    Klasse1 klasse1 = new Klasse1();
    klasse1.doFoo(IRGENDWAS);
  }
}
Ok, ein wenig konstruiert und absolut schlecht benannte Variablen, aber was du hier siehst ist das Problem, dass beide Klassen ein gleich benannte Konstante enthalten, die aber unterschiedliche Werte hat. Wenn Klasse2 etwas umfangreicher wäre, dann kannst du sehr leicht übersehen, dass du hier eine Konstante gleichen Namens defininert hast. Noch interessanter wird es, wenn du zwei verschiedene Dateien hast, die im import auftauchen. Beide enthalten entsprechend wieder eine gleich benannte Konstante mit unterschiedlichen Werten, welche würdest du jetzt korrekt übergeben?
Hier ist der Fall :
Code:
class Klasse2 {
  public static final int IRGENDWAS = -1;
 
  public void doFoo() {
    Klasse1 klasse1 = new Klasse1();
    klasse1.doFoo(Klasse1.IRGENDWAS);
  }
}
eindeutiger. Es wird ein Fehler vermieden der nicht gemacht werden braucht. Wie gesagt, es ist einfach Konvention. Das mit dem Leerzeilen nachträglich einfügen ist halt auch so eine Sache. Es kostet einfach weniger Zeit alles gleich zu tun.
Ich weiß nicht wie viel Erfahrung du schon mit größeren Projekten hast (wer in dem Alter studiert...)
Jedenfalls kommen immer wieder Leute, die sagen ihre Kommentare und die Formatierung folgt noch. Ich frage dann gerne häufiger nach wann. Habe es selten erlebt, dass das so wirklich klappt. Und wenn du mal etwas umfangreichere Projekte hast, an denen mehr als eine Person arbeitet, du wirst schnell merken dass ein Nachher zu spät ist. Bezieht sich hier nicht direkt auf deinen Code, ist vielmehr der Tipp es dir gleich richtig anzugewöhnen. Je später du so etwas machst, desto schwerer wird es dir fallen. Und glaub mir, deinem späteren Chef (oder dem aktuellen) wird es auch besser gefallen, wenn du gleich sauber arbeitest (wie gesagt, super unsauber ist das hier nicht!)

3_of_8 8. Jul 2006 21:10

Re: Visuelle Styles in Java
 
Mein größtest Projekt hatte bisher 10000 LOC.

Ich hab dann nen Source Formatter drübergejagt, bissel kommentiert und Leerzeilen eingefügt.

Der_Unwissende 8. Jul 2006 21:36

Re: Visuelle Styles in Java
 
Sorry, glaube wir sind schon ziemlich OT, aber egal.


Zitat:

Zitat von 3_of_8
Mein größtest Projekt hatte bisher 10000 LOC

Ok, was möchtest du mir denn damit sagen? Ich meine klar, Lines of Code sagen immer extrem viel aus, so grob gesagt gar nichts. Ich wette ich bekomme ein Projekt mit 100, 1000 oder 10000 Zeilen hin (selbe Funktionalität). Ist alles eine Frage der Zeilen. Was nachträgliches rüberlaufen lassen von einem Formater angeht, so klappt das vielleicht noch bei solchen kleinen Projekten, aber schon wenn du im Team arbeitest wird das etwas kritischer. Dann kommst du kaum um etwas wie ein CVS (o.Ä.) herum. Hier sollte Code immer so stehen, dass er zu jedem Zeitpunkt benutztbar ist. Ein bissel kommentieren ist da im Nachhinein nicht möglich. Es arbeiten einfach mal verschiedene Menschen am selben Abschnitt Code. Genau da kommt ja auch das C in CVS her. Wenn hier jmd. keinen Kommentar hinterlässt, dann weißt du einfach mal nicht wozu was genau gemacht wird. Da werden dann schnell ein paar wichtige Zeilen ersetzt, die nie hätten verändert werden sollen. Noch schöner ist es, wenn (wie so ziemlich immer) der erste Entwurf von Schnittstellen nachgebessert werden muss. Da macht es dann Spaß zu schauen, was eine unkommentierte Methode genau macht und ob sie für einen neuen Entwurf noch benötigt wird oder eben nicht.
Wie gesagt, ich weiß nicht welche Erfahrungen du da schon gemacht hast, früher oder später denke ich wirst du dann diese machen: "Mach es lieber gleich richtig!"
Der Satz stammt nicht von mir und ich habe mich auch lange genug nicht dran gehalten, aber es ist einfach so, dass du nie genug Zeit hast etwas im Nachhinein zu veränden. Wenn du an einem größeren Projekt für Geld arbeitest, dann gibt es in der Regel sehr konkrete zeitliche Vorstellungen. Bei einem aktuellen Projekt von mir, gehen unsere Kunden damit zu eigenen Kunden. Da sind dann wirklich Termine mit ihren Kunden abgemacht. Zudem schläft die Konkurrenz nicht, wenn die zu lange auf ihre Software warten, werden die sicherlich nicht mehr all zu viel Erfolg auf dem Markt haben. Fällt dies auf uns zurück, so kann ich mir dann auch schneller einen neuen Job suchen als mir lieb wäre. Fällt jetzt jmd. z.B. Krankheitsbedingt aus, so darf es hier also nicht zu einem unnötigen zeitlichen Engpass kommen. Würden hier alle Kommentare nachträglich eingefügt werden...
Ein weiteres Problem ist, dass die Softwareentwicklung immer agil bleiben sollte. Gerade wenn deine Kunden nicht aus der IT kommen, wirst du häufiger als du vielleicht glaubst das Problem haben, dass unklar ist was gemacht werden soll. Es gibt immer sehr grobe Vorstellungen, z.B. wir wollen eine Auswertung und einen Ausdruck. Wenn du daraus schließen kannst, wie die beiden Aussehen, dann stimme ich dir zu, mache alles nachträglich. In der Regel ist es aber so, dass du von Zeit zu Zeit ein wenig an der Vorstellung deiner Kunden vorbei entwickelst. Damit es nicht stark abweicht (dann wäre das Projekt für den ...) wirst du also in möglichst kurzen Iterationen eine Vorstellung beim Kunden abliefern und hier über neue Richtungen reden. Kann auch sein dass du 100%ig das Richtige tust, aber die Gewissheit tut gut! Wichtig ist, dass hier schnell Prioritäten gesetzt und geändert werden können. Davon profitieren dann wirklich beide Seiten. Da du aber weiterhin ein Zeitfenster hast, dass i.d.R. größer sein könnte, hast du einfach nicht die Zeit etwas im Nachhinein zu korrigieren. Alles was du nur als Prototyp erstellen wolltest, fließt dann plötzlich doch in die finale Version ein (ohne jede Veränderung).
So schön in solchen Fällen theoretische Evolutionsmodelle sind, sie sind in der Praxis nicht immer realisierbar.

Ok, sorry, ist wohl etwas umfangreicher OT gewurden. Meine das alles wirklich nicht als böse Kritik sondern als nett gemeinte Anregung. Um es einfach zu sagen, ich habe im Moment einen gewissen Einfluss auf Personalentscheidungen (natürlich nur in der einen Firma in der ich arbeite), aber da kann ich sagen, dass diese Arbeitsweise auf mich einen Einfluss hätte. Und ich denke es gibt da noch andere Menschen die ähnlich handeln.
So, damit lasse ich dich auch damit in Ruhe. Wie du deinen Code gestaltest ist und bleibt natürlich weiterhin deine Sache!


Alle Zeitangaben in WEZ +1. Es ist jetzt 11:42 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz