Custom Buttons oder Custom Combobox

DoppelFabi

Aktives Mitglied
Hey,

Ich habe ein kleines Programm programmiert.
Aber die ich finde die Standard Combobox und Buttons "Skins" so heeslig.
Ich habe davon gehört, dass man mit einer Grafikmethode irgendwie diese Skins selbst erstellen kann.
Gibt es Websiten oder Leute die mir das alles etwas erklären?

LG
Fabi
 
Geht es dir um Swing oder um JavaFX?

Falls ersteres:
Es kommt etwas drauf an, was du unter "Custom" verstehst.
Es gibt die verschiedene, vordefinierte, Look and Feels (LAF). Einfach mal danach googeln.
Falls du wirklich in die Richtung "fancy" mit polygon-förmigen Comboboxen gehen willst ( 😉 ), musst du tatsächlich deine Komponenten selber zeichnen. Dazu vielleicht einfach mal hier einlesen.

Falls letzteres:
In JavaFX kannst du dein Styling über CSS bestimmen.
 
Ich denke ich werde sie selber Zeichnen gibt es Beispiel Bilder wie so ein Custom Button, Combobox aussehen kann? Würde gerne eine Combobox, wo auf einer Seite ON steht auf der anderen OFF und wenn ich ihn Klicke soll eine Animation kommen. Die Animation sollte einfach nur das die eine Seite zur anderen wandert aber dann ON anzeigt und der Hintergrund des Buttons sollte dann Grün bzw. Rot werden.
 
Such bei Google einfach mal nach "Toggle Switch Button" ... da sollten genug Bilder kommen.
Das mit der Animation solltest du erstmal in der Hintergrund stellen - das ist nicht ganz so trivial. Bau erstmal den Button ohne Animation und füg diese danach hinzu.
 
Ich habe mich mal auf Google informiert und habe mir das Beispiel von Oracle angeschaut.
Bei mir hat sich eine Frage gebildet:
Dort sind 3 Buttons, aber ich bräuchte 2 und die Buttons dort sind alle "Rund" deswegen sieht es bisschen naja aus..
Aber ginge es, wenn man 2 Buttons (ON/OFF) nebeneinander packt, und denn Button auf einer Seite nur rund zu machen. Sprich (ON OFF) bei ON links rund und bei OFF rechts rund.
 
Warum willst du das ganze denn als 2 verschiedene Buttons abbilden? Es reicht doch vollkommen 1 Button zu nutzen und beim klick auf den Button das Bild zu wechseln. Intern hast du ein boolean für den State (on/off) und fertig ist das Ding. 😉
Somit hast du das Problem auch nicht mehr mit den Ecken weil du einfach alle Ecken abrunden kannst.

Aber um die Frage zu beantworten: in der Theorie wäre es möglich nur jeweils 2 Ecken abzurunden, ja.
 
Möchte in der Mitte des Button ein Strich oder was auch gut wäre ist ein Punkt der ganz rechts ist (Also OFF) und wenn ich drauf klicke mit Animation nach ganz rechts zu on wandert. Kennst du diese Minecraft Cheats? Dort sind öfters sowelche Animations drin. Nur dieses Beispiel kenne ich😕
 
Meinst du sowas?
Edit: (Link: https://www.digminecraft.com/game_commands/images/cheats_on_edu.png )
cheats_on_edu.png
 
Zuletzt bearbeitet:
Ich habe denn Screenshot von dir auf Google gefunden.
Das ist auch ein gute Beispiel.
Aber was natürlich geiler Aussehen würde ist, wenn es ein abgerundeten Buttom gibt, der rechts off und links on hat.
Und ein Punkt standardmäßig auf off steht und wenn drauf klicke, geht der Punkt von rechts nach links zu on.
Vielleicht schwer vorzustellen. 😀
 
Ja nur länger und das rechts und links on/off steht

EDIT: Was besser wäre: In denn Punkt on und wenn der Status geändert wird dementsprechend off
 
Auf denn 2ten Link kann ich erst nach der Arbeit.
Steht im 2ten Link, wie man das ungefährt programmiert?
Und wie programmiert man die Animation und das Custom Design?
 
Die Animation ist, soweit ich das sehe, bereits enthalten. Die CSS-Styles musst Du suchen. Ich verwende kein JavaFX, insofern kann ich da nicht viel mehr dazu sagen. Was Anpassungen betrifft: @Robat 🙂
 
Ich würde gerne JavaFX benutzen aber wenn es nicht anders geht dann CSS.
Das ist ein bisschen wie wenn du sagen würdest:
Ich würde meinen Kaffee gerne mit der Maschine machen - wenn das nicht geht trinke ich ihn ohne Milch 😛

JavaFX nutzt CSS Dateien um die Komponenten zu stylen. Ob du CSS nutzt hängt nicht davon ab ob du JavaFX benutzt 😉

Ansonsten hier mal ein kleiner Denkanstoß:
 
JavaFX und Swing zu mischen ist zwar technisch möglich, aber nicht empfehlenswert und hier überhaupt nicht nötig.

@mihe7 wird sicherlich gleich mit einem Beispiel um die Ecke kommen, daher halt ich mich mal zurück 😛

Übrigens: hast du mal in Erwägung gezogen selber zu googeln? Gibt doch bestimmt genug Zeug dazu im Netz
 
Ist derzeit nicht möglich, da dieser PC denn ich verwende mit einer FireWall mit einem Netzwerk verbunden ist von der Firma, sodass die meisten Websiten die nicht zum Arbeiten da sind, gesperrt sind.
 
Ich habe oft wenig zu tun, deswegen schreibe ich hier.
Gerade habe ich wieder einen Auftrag deswegen bin ich jetzt eine Stunde wieder nicht da.
Meine Hobbies bekommen nur Zeit, wenn keine Arbeit ansteht.
 
@mihe7 wird sicherlich gleich mit einem Beispiel um die Ecke kommen, daher halt ich mich mal zurück 😛
So schnell geht das auch wieder nicht 🙂

Hier mal ein Ansatz (Achtung: quick & dirty - vor allem dirty)

Java:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Insets;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JComponent;
import javax.swing.Timer;

// für Testzwecke (main)
import javax.swing.*;


public class SwitchButton extends JComponent {
    private String onLabel = "ON";
    private String offLabel = "OFF";
    private int gap = 10;
    private static final int DEFAULT_TRACK_WIDTH = 100;
    private static final int KNOB_DIAMETER = 20;

    private int trackHeight = 24;

    private int duration = 200;
    private int animX = -1;
    private Animator animator;

    private Color trackColor = Color.WHITE;
    private Color knobColor = Color.GREEN;

    private boolean on = false;

    public SwitchButton() {
        addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                if (animator == null || animator.timer == null) {
                    animator = new Animator(duration);
                }
            }
        });
    }

    @Override
    public Dimension getPreferredSize() {
        if (isPreferredSizeSet()) {
            return super.getPreferredSize();
        }

        FontMetrics fm = getFontMetrics(getFont());
        Insets insets = getInsets();
        int w = insets.left + insets.right;
        w += onLabelWidth() + offLabelWidth();
        w += 2 * gap + DEFAULT_TRACK_WIDTH;
        int h = insets.top + insets.bottom + 
                Math.max(trackHeight, Math.max(
                    KNOB_DIAMETER, fm.getHeight()));
        return new Dimension(w, h);
    }

    private int onLabelWidth() {
        FontMetrics fm = getFontMetrics(getFont());
        return fm.stringWidth(onLabel);        
    }

    private int offLabelWidth() {
        FontMetrics fm = getFontMetrics(getFont());
        return fm.stringWidth(offLabel);        
    }

    private int trackWidth() {
        Insets insets = getInsets();
        return getWidth() - insets.left - insets.right - 
            2*gap - onLabelWidth() - offLabelWidth();
    }

    @Override
    public Dimension getMinimumSize() {
        return getPreferredSize();
    }

    @Override
    protected void paintComponent(Graphics g) {
        Insets insets = getInsets();
        int lx = insets.left;
        int ty = insets.top;
        int h = getHeight() - insets.top - insets.bottom - 1;
        int w = getWidth() - insets.left - insets.right - 1;

        g.setColor(getBackground());
        g.fillRect(lx, ty, w, h);

        g.setFont(getFont());
        FontMetrics fm = g.getFontMetrics();

        int onWidth = onLabelWidth();
        int offWidth = offLabelWidth();

        int cy = h/2;
        int x = lx;
        g.setColor(getForeground());
        g.drawString(offLabel, x, cy + fm.getAscent() / 2);
        x += offWidth + gap;
        int onX = lx + w - onWidth;
        g.drawString(onLabel, onX, cy + fm.getAscent() / 2);        
        
        int trackX = x;
        int trackWidth = onX - gap - x;
        g.setColor(trackColor);
        g.fillRect(x, ty, trackWidth, h);    

        int knobX;
        int maxKnobX = trackWidth - KNOB_DIAMETER;
        if (animX != -1) {
            knobX = Math.min(Math.max(0, animX), maxKnobX);
        } else {
            knobX = on ? maxKnobX : 0;
        }
        int knobY = cy - KNOB_DIAMETER/2;
        g.setColor(knobColor);
        g.fillOval(trackX + knobX, knobY, KNOB_DIAMETER, KNOB_DIAMETER);
    }

    private void setAnimX(int x) {
        animX = x;
        repaint();
    }

    private class Animator {
        private Timer timer;
        private int direction;
        private int max;
        private long millis;
        private int duration;

        public Animator(int duration) {
            this.duration = duration;
            max = trackWidth();
            direction = on ? -1 : 1;
            millis = System.currentTimeMillis();
            timer = new Timer(15, e -> animate());
            timer.start();
        }

        private void animate() {
            int time = (int)(System.currentTimeMillis() - millis);
            if (time < duration) {
                setAnimX((direction < 0 ? max : 0) + direction * max * time / duration);
            } else {
                on = !on;
                setAnimX(-1);
                timer.stop();
                timer = null;
            }
        }
    }

    public static final void main(String[] args) {
        JPanel panel = new JPanel();
        panel.add(new SwitchButton());

        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.add(panel);
        frame.pack();
        frame.setVisible(true);
    }
}
 

Zurück
Oben