Editierbare JComboBox auf KeyEvents reagieren

  • Themenstarter Themenstarter Gelöschtes Mitglied 56712
  • Beginndatum Beginndatum
G

Gelöschtes Mitglied 56712

Gast
Guten Tag
Habe eine JComboBox .setEditable(true); gesetzt.

Jetzt kann ich ja Texteingaben im Feld (welches?) machen.
Soweit so gut.

Aber wie und an was hänge ich nun einen KeyListener der mir die aktuellen Tastatureingaben auswirft?
Ausser auf die "Enter-Taste" reagiert bei mir nichts.

Irgendwie finde ich bei der ComboBox das Objekt nicht in dem ich gerade Schreibe und das mir die aktuell gedrückte Taste zurückgeben kann.
JComboBox.getEditor() kennt nur einen ActionListener... 🙄

Was bei mir nicht geht:
comboBox.addKeyListener(new KeyAdapter() {...});

Vielen Dank für Hilfestellung.
Richi
 
Zuletzt bearbeitet von einem Moderator:
Schau Dir mal ComboBox.getEditor().getEditorControl() an. Das gibt dir das Control, in das der User etwas eingibt. Das sollte eine JTextField sein.

Da kannst Du dann auch einen KeyListener hinzufügen.
 
BINGO
genau DAS habe ich gesucht!
Funktioniert jetzt! Vielen Dank

Muss gecastet werden:
Java:
JTextField cmbText = (JTextField) comboBox.getEditor().getEditorComponent();

Damit kann ich super Arbeiten... 😇
Vielen Dank.
Richi

PS:
Auch der FocusListener geht jetzt (...selectAll())
 
Früher konnte ich eine JComboBox die eine Breite von 180px hat erstellen. (geht auch heute noch)
Wenn jetzt die Inhalte breiter als 180px sind, wurde das ComboBox - Popup in der Breite angepasst!
d.H. das Popup wurde auf 350px(resp. den breitesten Inhalt) erweitert, wenn es auf visible gesetzt wurde.
Also wurde der ganze Zeilen-Inhalt im Popup angezeigt.

Wie schaffe ich es, dass das wieder möglich ist?
So dass das Popup entsprechend breiter ist als die JComboBox und den breitesten Text ganz anzeigt?

Welche Komponente muss ich da abgreifen und anpassen?
 
Ich verstehe das generelle Problem noch nicht. Ist Dein Problem, dass die Breite nicht angepasst wird, wenn neue Werte hinzu kommen oder was ist genau das Problem?

Ansonsten schau Dir mal die folgende Methode an: setPrototypeDisplayValue.

Eine weite Möglichkeit der Steuerung wäre ein eigener ListCellRenderer incl eben dem Setzen des gewünschten Wertes bei getPreferredSize.

Zu guter letzt kannst Du eine komplett eigene Logik für die Erstellung der PopUp Elemente erstellen (über setUI Methode). Aber das dürfte vermutlich einfach nur Overkill sein.
 
Also z.B. Eintrag x:
x = "Ich bin nicht sehr Versiert"

im Textfeld der ComboBox wird mir sowas wie:
"Ich bin nicht se" angezeigt, weil die Breite nur das anzeigen lässt.

Jetzt wollte ich, dass wenn das Popup visible ist, es so breit angezeigt wird, dass ich den ganzen Text sehe:
"Ich bin nicht sehr Versiert"

Nur schaffe ich es nicht, dass das Popup breiter angezeigt wird als die JComboBox welche ich mit getBounds(x, y, 150, 22) gesetzt habe.
Geht das überhaubt, oder empfiehlt es sich mit JTextField(), List() und einem JButton() eine eigene ComboBox zu basteln?
Stichwort Overkill

Vielen Dank.
 
Als erstes: Bei so Problemen kann es helfen, immer ein kleines Beispiel zu gestalten, dass das Problem aufzeigt.

Das Kernproblem hier ist, dass DU mit setBounds eine Control-Breite vorgibst und das Popup hat die gleiche Breite wie das Control selbst.

Du kannst eine eigene Breite für das Popup vorgeben, wenn Du möchtest. Ein Beispiel dafür wäre z.B.:
Java:
package de.kneitzel;

import javax.swing.*;
import javax.swing.plaf.basic.BasicComboBoxUI;
import javax.swing.plaf.basic.BasicComboPopup;
import javax.swing.plaf.basic.ComboPopup;
import java.awt.*;

public class JFrameTest {
    public static void main(String[] args) throws Exception {
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(800, 500);
        frame.setLayout(null);
        JComboBox<String> comboBox = new JComboBox<>();
        comboBox.setModel(new DefaultComboBoxModel<>(new String[] {"A", "B", "C", "D", "E", "F", "Ich bin nicht sehr Versiert"}));
        comboBox.setEditable(true);
        comboBox.setBounds(10, 10, 150, 22);
        comboBox.setUI(new BasicComboBoxUI() {
            @Override
            protected ComboPopup createPopup() {
                BasicComboPopup popup = new BasicComboPopup(comboBox) {
                    @Override
                    protected Rectangle computePopupBounds(int x, int y, int width, int height) {
                        int desiredWidth = 200;
                        // Hier wird die Breite des Popups auf mindestens 250px gesetzt,
                        // auch wenn das Control selbst schmaler ist.
                        return super.computePopupBounds(x, y, Math.max(width, desiredWidth), height);
                    }
                };
                return popup;
            }
        });
        frame.add(comboBox);
        frame.setVisible(true);
    }
}

Die Breite des Controls ist 150 und das Popup ist breiter: 200.
In dem super.computePopupBounds kannst Du das Popup auch noch beliebig verschieben und so ...
 
Vielen, vielen Dank! 😇
Genau das habe ich gesucht.
Java:
       ...
        comboBox.setUI(new BasicComboBoxUI() {
            @Override
            protected ComboPopup createPopup() {
                BasicComboPopup popup = new BasicComboPopup(comboBox) {
                    @Override
                    protected Rectangle computePopupBounds(int x, int y, int width, int height) {
                        int desiredWidth = 200;
                        // Hier wird die Breite des Popups auf mindestens 250px gesetzt,
                        // auch wenn das Control selbst schmaler ist.
                        return super.computePopupBounds(x, y, Math.max(width, desiredWidth), height);
                    }
                };
                return popup;
            }
        });

Einfach GENIAL!
Hab es grad bei mir implemnetiert!!! --- Weihnachten kann kommen! 😁😁😁
Vielen Dank
Richi
 
Noch ein kleines Problem:
Ich möchte, dass beim KeyEvent.VK_DOWN das Popup der ComboBox NICHT auf visible gesetzt wird.
(also nicht angezeigt wird)

Aequivalent zu KeyEvent.VK_UP lässt sich das einrichten?

Wenn ich KeyEvent.VK_DOWN drücke, möchte ich dass einfach der nächste Eintrag selektiert wird ohne Popup-Menu.
Das Popup der ComboBox soll nur dann angezeigt werden wenn ich auf den DropDown-Pfeil klicke...

Kann man sowas einstellen / proggen?
Wenn ich comboBox.setPopupVisible(false) mache, blitzt trotzdem kurz das Popup auf und schliesst sich wieder.
(e.consume() hilft da offensichtlich nicht)
Optisch ist das nicht angenehm.

Bei KeyEvent.VK_UP popt es ja auch nicht.
 
So... hier mal den Code welchen ich Dank diesem Forum hingekriegt habe:
(wenn es irgend Jemanden intressiert)

Java:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import java.awt.GraphicsEnvironment;
import java.awt.Rectangle;

import javax.swing.DefaultComboBoxModel;
import javax.swing.JComboBox;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.plaf.basic.BasicComboBoxUI;
import javax.swing.plaf.basic.BasicComboPopup;
import javax.swing.plaf.basic.ComboPopup;

import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;

public class TestCombo extends JDialog {

    private static final long serialVersionUID = 1L;
    static Font myFont = new Font("Arial", Font.PLAIN, 12);
    static Font lastFont = new Font("Noteworthy", Font.PLAIN, 18);
    static int index;
    static String[] allFonts;
    static int maxW = 0;
 
    @SuppressWarnings({ "unchecked", "rawtypes" })
    public TestCombo() {
        setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
        setModal(true);
        setBounds(300, 300, 300, 300);
     
        GraphicsEnvironment gen = GraphicsEnvironment.getLocalGraphicsEnvironment();
        allFonts = gen.getAvailableFontFamilyNames();
     
        System.out.println("1. allFonts.length = "+allFonts.length);
        Font[] fAll = gen.getAllFonts();
        String addFnts = "";
        for(Font f : fAll) {
            String fNam = f.getFontName();
            if(f.canDisplayUpTo(fNam) < 0) {
                addFnts += ","+fNam;
            }
        }
     
        JLabel testTF = new JLabel();
        testTF.setText("<html>"+addFnts.substring(1).replaceAll(",", "<br>")+"</html>");
        testTF.updateUI();
        maxW = testTF.getPreferredSize().width+28;    //Breite+ Vertical-Scrollbar plus ein wenig Abstand
        allFonts = addFnts.substring(1).split(",");
     
        System.out.println("2. allFonts.length = "+allFonts.length);
     
        String lastUse = "Noteworthy";
        setLocationRelativeTo(null);
     
        JPanel center = new JPanel();
        getContentPane().add(center, BorderLayout.CENTER);
        center.setLayout(null);
     
        JLabel fontMuster = new JLabel();
        fontMuster.setText("Muster Text");
        fontMuster.setVerticalAlignment(0);
        fontMuster.setBounds(20, 200, 150, 50);
        fontMuster.setFont(lastFont);
        center.add(fontMuster);
     
        Rectangle forNC = new Rectangle(20, 10, 190, 24);
        JComboBox<Object[]> nc = new JComboBox<>();
        nc.setModel(new DefaultComboBoxModel(allFonts));
        nc.setEditable(true);
        nc.setBackground(Color.WHITE);
     
        nc.setUI(new BasicComboBoxUI() {
            @Override
            protected ComboPopup createPopup() {
                BasicComboPopup popup = new BasicComboPopup(comboBox) {
                    private static final long serialVersionUID = 1L;
                    @Override
                    protected Rectangle computePopupBounds(int x, int y, int width, int height) {
                        int desiredWidth = maxW;
                        // Hier wird die Breite des Popups auf mindestens maxW gesetzt,
                        // auch wenn das Control selbst schmaler ist.
                        return super.computePopupBounds(x, y, Math.max(width, desiredWidth), height);
                    }
                };
                return popup;
            }
        });
     
     
     
        JTextField cmbText = (JTextField) nc.getEditor().getEditorComponent();
        cmbText.addFocusListener(new FocusAdapter() {
            @Override
            public void focusGained(FocusEvent e) {
                cmbText.selectAll();
            }
        });
     
        nc.setName("fontListe");
        nc.setDoubleBuffered(true);
        nc.setBounds(forNC);
        cmbText.addKeyListener(new KeyAdapter() {
            @Override
            public void keyReleased(KeyEvent e) {
                if(e.getKeyCode() == KeyEvent.VK_UP) {
                    index--;
                    if(index < 0) {;
                        index = nc.getItemCount()-1;
                    }
                    nc.setSelectedIndex(index);
                }
                else if(e.getKeyCode() == KeyEvent.VK_DOWN) {
                    e.consume();
                    nc.setPopupVisible(false);
                    index++;
                    if(index >= nc.getItemCount()) {;
                        index = 0;
                    }
                    nc.setSelectedIndex(index);
                }
                else if(e.getKeyCode() != KeyEvent.VK_SHIFT && e.getKeyCode() != KeyEvent.VK_ALT && e.getKeyCode() != KeyEvent.VK_ALT_GRAPH
                         && e.getKeyCode() != KeyEvent.VK_CONTROL && e.getKeyCode() != KeyEvent.VK_END
                         && e.getKeyCode() != KeyEvent.VK_HOME) {
                    //-----------------------------------------------------------------------------------------------
                    String oT = cmbText.getText();
                    int searchIndex = 0;
                    String valCMB = "";
                    for(Object s: allFonts) {
                        if(((String) s).startsWith(oT)) {
                            break;
                        }
                        searchIndex++;
                    }
                    if(searchIndex >= 0 && searchIndex < nc.getItemCount()) {
                        index = searchIndex;
                        nc.setSelectedIndex(searchIndex);
                        valCMB = ""+nc.getSelectedItem();
                    }
                    cmbText.setSelectionStart(oT.length());
                    cmbText.setSelectionEnd(cmbText.getText().length());
                    if(valCMB.equals(oT)) {
                        nc.setPopupVisible(false);
                    }
                    else {
                        nc.setPopupVisible(true);
                    }
                 
                }
            }
         
        });
        nc.addItemListener(new ItemListener() {
            @Override
            public void itemStateChanged(ItemEvent e) {
                if(e.getStateChange() == ItemEvent.SELECTED){
                    new Thread(new Runnable() {
                        @Override
                        public void run() {
                            String valFnt = ""+nc.getSelectedItem();
                            System.out.println("Auswahl geändert!\t"+valFnt);
                            fontMuster.setFont(new Font(valFnt, lastFont.getStyle(), lastFont.getSize()));
                        }
                    }).start();
                }
            }
        });
        center.add(nc);
     
        for(Object s: allFonts) {
            if(((String) s).startsWith(lastUse)) {
                break;
            }
            index++;
        }
        if(index >= 0 && index < nc.getItemCount()) {
            nc.setSelectedIndex(index);
        }
     
        setVisible(true);
        System.exit(0);
    }
 
    //🇨🇭️🇨🇭️🇨🇭️🇨🇭️🇨🇭️🇨🇭️🇨🇭️🇨🇭️🇨🇭️🇨🇭️🇨🇭️🇨🇭️🇨🇭️🇨🇭️🇨🇭️🇨🇭️🇨🇭️🇨🇭️🇨🇭️ Start TestCombo (MAIN) 🇨🇭️🇨🇭️🇨🇭️🇨🇭️🇨🇭️🇨🇭️🇨🇭️🇨🇭️🇨🇭️🇨🇭️🇨🇭️🇨🇭️🇨🇭️🇨🇭️🇨🇭️🇨🇭️🇨🇭️🇨🇭️🇨🇭

    public static void main(String[] args) {
        new TestCombo();
    }
}

Es ging mir vorallem darum, dass alle lesbaren Schriften zur Auswahl stehen.
Dass die ComboBox editable ist und man, auch wenn man die schreibweise des Fontnames nicht korrekt weiss, schon mit
den ersten paar Buchstaben eine Auswahl bekommt.
Wenn eine Auswahl angezeigt wird kann man mit :
KeyEvent.VK_UP
KeyEvent.VK_DOWN

zum vorherigen, resp. nächsten Eintrag switchen.

Auf diesem PC gibt es gemäss:
Code:
        GraphicsEnvironment gen = GraphicsEnvironment.getLocalGraphicsEnvironment();
        allFonts = gen.getAvailableFontFamilyNames();
2106 verfügbare Schriften. (Bei sovielen Schriften, kann ich mir die genaue Bezeichnung nicht merken)
Lesbare Fonts: 1297.

Obiger Code erfüllt jetzt den Zweck der erleichterten Schrift-Auswahl.
Einziger Wermutstropfen: bei KeyEvent.VK_DOWN (und nur bei KeyEvent.VK_DOWN) popt das ComboBox.Popup auf,
welches ich mit .setPopupVisible(false); gleich wieder ausblende, da ich ja nur zum nächsten Eintrag navigieren will.

PS:
Das Ganze ist vlt. etwas dilettantisch... aber ausbaufähig und für mich reicht es, bis auf das aufpoppen bei VK_DOWN.
 
Zuletzt bearbeitet von einem Moderator:
Das ganze Programm ist ein Construktor. Die Schleife am Ende ist merkwürdig. allFonts ist ein String-Array aber du verwendest Objekt und castest dann auf String! Ich glaube mehr will ich gar nicht sehen.
Das kannst du besser. Programme mit grafischer Oberfläche sind oft schlecht aufgebaut, aber besser geht das schon.
 
@Oneixee5
Das kannst du besser.
Erstmal vielen Dank für das Vertrauen...
...und tatsächlich hab ichs besser hingekriegt. 🙂

Es ging mir ja nur um Die JComboBox.
Code:
comboBox.getSelectedItem();
verlangt immer: Add cast to -> String, Integer, Boolean, Date(), usw.

Habe mit instanceOff versucht den "getSelectedItem()" zu definieren.
Es wurde immer in (... instanceoff Object) ausgeworfen.
Darum ging ich davon aus, dass das Model alles nach Objekt parst.

Ich könnte ja ein ComboBoxModel überschreiben...
Wäre aber nicht mehr Allgemeingültig.

aber du verwendest Objekt und castest dann auf String!
Danke, aber egal was ich übergebe, muss ich bei "getSelectedItem()" in das gewünschte parsen. (String, Date(), long, int, usw.)
wenn ich die Info weiter verwenden will.

Im Model der ComboBox werden Informationen in den Formen wie: Date().getTime, long, integer, usw. eingetragen. (offensichtlich ALLES als Objects)
Im Renderer werden diese Infos entsprechend als STRING geparst und ausgegeben.
Genau da lag bei mir der Fehler... mit "getSelectedItem()" wird mir nicht der Eintrag des Models zurückgegeben sondern der Text in der
JComboBox.

Mit getSelectedIndex(x) wird mir aber offensichtlich der Model-Eintrag zurückgegeben.
Diese Rückgabe kann ich jetzt ggF. ohne zu Parsen verwenden.

Habe ich das jetzt richtig verstanden?
 
Swing ist eine sehr alte API/Framework. Swing stammt aus einer Zeit vor Generics (Generic<type>). Daher muss Swing oft kompatibel zu den alten Versionen bleiben und fällt dann zurück auf Object als Rückgabe oder Parameter.

Grafische Oberflächen in Java stammen aus der Zeit der Applets, also sind quasi Relikte aus der Steinzeit(letztes Jahrtausend) - und sollen auch heute noch weitgehend kompatibel dazu sein. Heute dienen grafische Oberflächen in Java dazu, dass Anfänger etwas buntes sehen und nicht gleich die Lust verlieren. Man hat zwar immer wieder versucht grafische Oberflächen für Java zu etablieren aber das hat sich eigentlich nie durchgesetzt. Sie funktionieren immer etwas anders als das OS vorgibt (was ja in Java auch gewollt ist, -> Plattform-Unabhängigkeit) und sind damit immer Aliens für das Betriebssystem bzw. Desktopumgebung.

Möchte man ernsthaft grafische Oberflächen erstellen, dann sollte man direkt die Bibliotheken bspw. von Windows verwenden und eine entsprechende Programmiersprache.
Die Stärken von Java liegen im Bereich der Server. Grafische Oberflächen kann man dem Browser überlassen oder den Apps. Man muss sich fragen, wozu überhaupt noch native grafische Oberflächen benötigt werden. Verwaltung, Office, Akten - das alles wird heute im Browser verarbeitet. Selbst Systemverwaltung im professionellem Umfeld sind Browseranwendungen. Administratoren verwenden die Kommandozeile oder die Browseranwendungen der Hersteller um größere Umgebungen zu managen.
Fazit ist also, nur im Heim- und Hobbybereich benötigt man noch native grafische Oberflächen, weil die Anwender nicht über das nötige Wissen verfügen um mit der Kommandozeile zu arbeiten oder eine Webumgebung für die (Geräte-)Verwaltung zu etablieren.
Oder als Apps - da die mobilen Geräte zwar vom Nutzer bezahlt werden, der Nutzer jedoch normalerweise keinen Vollzugriff darauf hat. Es wäre auch etwas komisch auf dem Smartphone in der Konsole zu telefonieren. Mit KI werden aber auch hier die grafischen Oberflächen verschwinden. Dabei meine ich nicht die Anzeige von Dokumenten oder Videos, sondern die Bedienung.

Daher antworte ich normalerweise nicht mehr zu Themen zu Java-UI's. Die Antwort in #11 bezog sich auch nicht auf die JComboBox, sondern auf die Art und Weise wie das Programm erstellt wurde.
 
Zuletzt bearbeitet:
Ich könnte ja ein ComboBoxModel überschreiben...
Wäre aber nicht mehr Allgemeingültig.
Nicht notwendig. Sowohl JComboBox als auch ComboBoxModel unterstützen Generics. Unabhängig davon: In Swing sind Models dazu da, implementiert/überschrieben zu werden. Da muss nichts allgemeingültig sein.

Java:
class Test {

    public void run() {
        GraphicsEnvironment gen = GraphicsEnvironment.getLocalGraphicsEnvironment();
        JComboBox<String> fontNameSelection = new JComboBox<>(gen.getAvailableFontFamilyNames());
        JButton button = new JButton("Setzen");
        button.addActionListener(e -> {
            String selectedFontName = getSelectedItem(fontNameSelection).orElse("nix");
            JOptionPane.showMessageDialog(button, "Setze " + selectedFontName);
        });

        Box content = Box.createVerticalBox();
        content.add(new JLabel("Schriftart"));
        content.add(fontNameSelection);
        content.add(button);
  
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.add(content);
        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> new Test().run());
    }

    public static <E> Optional<E> getSelectedItem(JComboBox<E> cmb) {
        int index = cmb.getSelectedIndex();
        return index < 0 ? Optional.empty() : Optional.of(cmb.getItemAt(index));
    }
}
 
Wie kommst du denn zu diesen Einschätzungen?
Die Einschätzung teile ich zu einem sehr großen Teil. UIs in Java sind einfach ein Problem.
  • SWT und JavaFX haben beide einen native Anteil, der einem mindestens die Portabilität nimmt.
  • Swing bietet von sich aus, kaum irgendwelche Möglichkeiten, die moderne UI Entwicklung ausmachen.
  • Es gab einige Libraries, die diese Frameworks ergänzt haben, aber die sind eigentlich alle verschwunden oder werden zumindest nicht mehr aktualisiert.

Ich habe JavaFX mal für eine taugliche Alternative gehalten, incl. mmvmFX Library. Aber die mvvmFX Library wird auch schon einige Zeit nicht mehr aktualisiert, so dass ich sie nicht mehr mit gutem Gewissen empfehlen kann.

Java bietet ansonsten auch viel zu wenig bezüglich Delivery Methoden und so. JPackage ist schon recht nett aber damit ist man aus meiner Sicht immer noch weit weit hinter den Möglichkeiten, die andere Umfelder so haben.
Ich weiß nicht, ob C# besser wäre...
Ich denke schon. Hier gibt es einige sehr interessante Ansätze. MAUI mit oder ohne Blazor finde ich sehr gut. Ich selbst habe diesen Stack einige Zeit für mich für Desktop Anwendungen ausgewählt.

Hier mag mancher sagen, dass man beim Deployment ähnliche Probleme hat, weil ja ein .Net Framework benötigt wird oder so, aber da gibt es deutlich mehr Ansätze und Lösungen.

Man muss auch nur einmal schauen, was der Markt so unterstützt oder eben nicht unterstützt. Gibt es irgendwelche 3rd Level UI Libraries für Swing, JavaFX oder SWT? Im .Net Umfeld wird man zugeschmissen mit Anbietern...

Aber wozu noch Desktop Anwendungen? Wo macht das noch wirklich Sinn? Es geht immer mehr Richtung Webanwendungen. Mit PWAs wird dann sehr viel unnötig. Das sieht man in vielen Produkten, wie gut das geht. Und wenn es doch eine Anwendung sein soll: Dann nutzt man halt eine Lösung, die sowas kapselt.
 
@KonradN
Aber wozu noch Desktop Anwendungen? Wo macht das noch wirklich Sinn? Es geht immer mehr Richtung Webanwendungen. Mit PWAs wird dann sehr viel unnötig. Das sieht man in vielen Produkten, wie gut das geht. Und wenn es doch eine Anwendung sein soll: Dann nutzt man halt eine Lösung, die sowas kapselt.
Wozu Web-Anwendungen, wenn der PC kein Internet und keinen lokalen Server hat auf dem ein WEB simulliert resp. Apache, PHP o. ähnliches installiert werden kann?

Systemverwaltung im professionellem Umfeld sind Browseranwendungen. Administratoren verwenden die Kommandozeile oder die Browseranwendungen der Hersteller um größere Umgebungen zu managen.
Fazit ist also, nur im Heim- und Hobbybereich benötigt man noch native grafische Oberflächen, weil die Anwender nicht über das nötige Wissen verfügen um mit der Kommandozeile zu arbeiten oder eine Webumgebung für die (Geräte-)Verwaltung zu etablieren.
Dann wäre ich daran Intressiert, wie Sie eine Schrift per Komandozeile auswählen (bei mehr als 1000 verfügbaren Schriftarten) ohne GUI.
Ich möchte ja dann sehen wie die gewählte Schrift aussieht und ggF. eine andere auswählen. Wohlverstanden ohne GUI.
Schon ein Popup ist eine GUI.

Aber nun zum eigentlichen Problem von mir:
folgender Code funkitioniert (mein Unwissen vorausgesetz) nur super, wenn ich exakt nur einmal eine ComboBox verwende.
Java:
       ...
        comboBox.setUI(new BasicComboBoxUI() {
            @Override
            protected ComboPopup createPopup() {
                BasicComboPopup popup = new BasicComboPopup(comboBox) {
                    @Override
                    protected Rectangle computePopupBounds(int x, int y, int width, int height) {
                        int desiredWidth = 200;
                        // Hier wird die Breite des Popups auf mindestens 250px gesetzt,
                        // auch wenn das Control selbst schmaler ist.
                        return super.computePopupBounds(x, y, Math.max(width, desiredWidth), height);
                    }
                };
                return popup;
            }
        });
Möchte ich meine MyComboBox mehrmals vewenden, haben alle dank BasicComboBoxUI() das gleiche Verhalten, resp. Einstellungen werden ausgehebelt.

Was mir aber vorschwebt, ist dass ich meine MyComboBox (geerbt von JComboBox) mehrmals in der gleichen GUI mit anderer Breite und anderen Einstellungen vewenden kann.

Wenn das wirklich nicht möglich sein sollte, bitte ich um Bestätigung.
Dann müsste ich selbst etwas bauen:
  • Einen eigenen Renderer.
  • Eine List mit den gewünschten Methoden inkl. Model aufbauen, welche in der Breite angepasst werden kann
  • Ein PopuMenu mit einem ScollPane in der die List angezeigt wird.
  • Das Textfeld zur anzeige der Auswahl hat
Der PC auf dem mein Programm laufen soll hat kein Internet und keine LAN Verbindung aus Sicherheitsgründen.
Die Drucker sind alle per USB angeschlossen.

Vielen Dank.
 
Dann wäre ich daran Intressiert, wie Sie eine Schrift per Komandozeile auswählen (bei mehr als 1000 verfügbaren Schriftarten) ohne GUI.
Ich möchte ja dann sehen wie die gewählte Schrift aussieht und ggF. eine andere auswählen. Wohlverstanden ohne GUI.
Schon ein Popup ist eine GUI.
Ich habe seit 1999/2000 einen Printserver im Portfolio. Dieser wird im Umfeld der öffentlichen Verwaltung in geschlossenen Netzwerken eingesetzt. Egal ob Einzeldruck oder Seriendruck, Frankiermaschinen inkl. automatischer Verpackung und Versand in Druckereien. Er wird ausschließlich per Browser bedient. Es ist selbst möglich einen Bericht zu generieren, indem natives SQL eingegeben wird. Selbstverständlich ist es auch möglich verschiedene Schriftarten einzustellen und zu betrachten.
Wozu Web-Anwendungen, wenn der PC kein Internet und keinen lokalen Server hat auf dem ein WEB simulliert resp. Apache, PHP o. ähnliches installiert werden kann?
Das ist einfach Unkenntnis. Internet ist für einen Server nicht notwendig. Ein Server ist einfach eine Software mit Schnittstellen zu einem Netzwerk, auch virtuelles Netzwerk. Ein Netzwerk muss nicht über mehrere Rechner gespannt sein. Man kann Server eigentlich in jeder Programmiersprache erstellen, auch bspw. in JavaScript. Manchmal sind dazu aber externe Bibliotheken notwendig. Oft ist selbst eine Rechtschreibkorrektur eine Serveranwendung. Auch die Sprachunterstützung in der Java-IDE ist idR. ein Server, bspw. https://github.com/eclipse-jdtls/eclipse.jdt.ls in Eclipse und in VSCode. Ein PC völlig ohne irgendwelche Netzwerkschnittstellen ist natürlich möglich. Wozu sollte man aber dort eine Schrift auswählen können. Man bekommt ja keine Daten dahin, welche man drucken oder optisch aufbereiten müsste.

Anwendungen als Server sind auch nichts neues. Hier mal die Ansicht von einem alten Drucker:
1733849433569.png
 
Zuletzt bearbeitet:
Wozu Web-Anwendungen, wenn der PC kein Internet und keinen lokalen Server hat auf dem ein WEB simulliert resp. Apache, PHP o. ähnliches installiert werden kann?
Der erste Punkt, der wichtig ist: Bei so Aussagen kommt eine Verallgemeinerung hinzu. Natürlich mag es Ausnahmen geben. Aber das ist definitiv eine Nische. Selbst mein Rauchmelder ist 24/7 per IoT Mobilvertrag online (Der ist in einer Hütte auf einem Campingplatz). Die Geräte sind heute doch fast alle online.

Und ich habe doch auch Möglichkeiten genannt. Es gibt Frameworks um eine Webanwendung auf dem Desktop bereit zu stellen. Webanwendung ist dabei als eine Anwendung zu verstehen, die auf einem HTML/CSS/JS Stack basiert. Auf dem genannten Rechner kannst Du ja auch Visual Studio Code installieren, oder? Und das ist eine HTML/CSS/JS Anwendung, die Dank Electronjs wie eine Desktop-Anwendung daher kommt.

Und dann kommt halt einfach, dass es viel zu wenig professionelle Desktop-Entwicklung mit Java gibt. Daher lohnt es sich für Firmen nicht, hier irgendwelche Frameworks zu pflegen. Und die Chance ist groß, dass sich jemand, der sich intensiv mit Desktop UIs beschäftigt, dann zu anderen Technologien zuwendet, da die deutlich mehr bieten.

Der Markt ist bei anderen Technologien einfach vorhanden. Und dann gibt es Anbieter wie Telerik oder GrapeCity, die dann UI-Kits bereitstellen. HTML/CSS Entwicklung mit Angular oder React ist Mainstream - das gibt es also. Die c# Technologien werden unterstützt ... Und sowas gibt es auch frei - bei React nehme ich gerne MUI um schnell und einfach gute Controls zu haben.

Du musst ja nur schauen, wie Du hier diverse Probleme beheben musst und was das für ein Gefrickel ist (Sorry, nicht abwertend gegen Deine Person gemeint - das ist halt ein Problem mit den Technologien. Wenig Controls, wenig Einstellmöglichkeiten ... Einstellungen im Code ... Das hat mit moderner Softwareentwicklung aus meiner Sicht wenig zu tun. Mit JavaFX hätte man das aber tatsächlich etwas weniger ...

Was mir aber vorschwebt, ist dass ich meine MyComboBox (geerbt von JComboBox) mehrmals in der gleichen GUI mit anderer Breite und anderen Einstellungen vewenden kann.

Wenn das wirklich nicht möglich sein sollte, bitte ich um Bestätigung.
Ja natürlich geht das. Du kannst in Swing Deine eigenen Controls bauen und diese dann entsprechend an beliebigen Stellen nutzen. Dabei ist aber die Frage: Erben von JComboBox oder ist es nicht besser, wenn Du ein Control hast, das dann intern eine JComboBox hat? Das gibt Dir deutlich mehr Unabhängigkeit. Wer sagt, dass Du morgen nicht ganz auf die JComboBox verzichtest und Du alles schöner/besser selbst entwickeln willst. So Du die JComboBox als internes Implementatios-Detail behältst, hast du hier alle Optionen offen.
(Schau dazu mal im Web nach "Composition over Inheritance" - da findet sich einiges zu!)
 
Anwendungen als Server sind auch nichts neues. Hier mal die Ansicht von einem alten Drucker:
Ist aber ein Netzwerkdrucker... (192.168.178.20 -> FritzBox)
Habe ich grad mal bei meinem Canon-Drucker ausprobiert... 🙁 (hat ja ohne NW-Anbindung !!! keine NW-Adresse) geht nicht!

Mein System ist LM22 Mate.
Somit kann (und will) ich die Geräte-Software vom Hersteller so nicht installierten.
Firefox meldet "Seite kann nicht gefunden werden" (Logisch: KEIN Internet, KEIN LAN, KEIN W-LAN)
Einfach nur USB thats all!

Bin ich hier nicht in den Anfänger-Themen gelandet?
Wenn nicht, dann bitte ich vielmals um Entschuldigung!!!
Andernfalls darf ich doch davon ausgehen dass hier
Java:
Das ist einfach Unkenntnis
erlaubt sein darf!
 
Auf dem genannten Rechner kannst Du ja auch Visual Studio Code installieren, oder?
Bei LM nur auf Umwegen.
Und die Chance ist groß, dass sich jemand, der sich intensiv mit Desktop UIs beschäftigt, dann zu anderen Technologien zuwendet, da die deutlich mehr bieten.
Meine extrem kleine Anwendung soll ausschlisslich LOKAL und ohne Internetanbindung (auch nicht mit einem SimultanBrowser) laufen.

Bis jetzt kann ich dank java Properties (os.name) in allen gängigen OS per Terminal / CMD die gewünschten Drucker infos auslesen!
Diese gelesenen Infos brauche ich um den Anwender zu informieren wenn sein Etikett nicht zum Durcker passt! (Randlos, druckbarer Bereicht, etc)

Aber die Schriften sind lokal gespeichert! Und diese will ich auslesen und anbieten!
Zusätzlich eine weitere ComboBox mit den Schriftgrößen!

Habe es jetzt gelößt!!!
  • JPanel als Basis
  • JTextField als Inputfeld
  • JLabel als DropDown - Pfeil
  • JPopupMenu als Popup
  • JList mit den gewünschten Einträgen
Alles mit den entsprechenden MouseListener, KeyListener und weiteren Methoden versehen!
Das JPopup wird mit pack() an den breitesten Eintrag angepasst. Sollte die Breite grösser sein als die MonitorBreite:
Java:
ava.awt.Toolkit.getDefaultToolkit().getScreenSize().width/2
wird ein ToolTip angezeigt

Vielen Dank an Alle.
Das Problem hat sich GELÖSST! 😄
Richi
 
Zuletzt bearbeitet von einem Moderator:
Wenn es ein Netzwerk Drucker ist. Dann kann könnte mann auch mit festen IP Adressen arbeiten. Also ohne DHCP.
Habe ich vergessen zu schreiben, dass alle Drucker nur per USB am PC hängen?
Ohne Software des Geräteherstellers kann es via USB nur über das Terminal gehen.
 
Selbst mein Rauchmelder ist 24/7 per IoT Mobilvertrag online
Sorry @KonradN
Solche Geräte kommen bei mir nicht zum Einsatz.
Es hilft ja nicht, dass die ganze Welt weiss, dass meine Hütte brennt!

Mein Rauchmelder der in meiner Maiensäss installiert ist, überflutet den Brandherd mit den Löschmitteln die hinterlegt sind, und zwar ganz gezielt!
(Wasser, Löschschaum, Stickstoff, usw..)

Dieser läuft auf "Raspberry Pi" und ist mit allen benötigten Sensoren ausgestattet und hat selbständig zugriff auf die Löschmittel.
Das ist reine Konsolenanwendung!
(eigenprodukt)

Was nützt mir ein Rauchmelder der mir mitteilt (mittels App), dass mein Alphütte brennt, aber diesen Brand nicht löschen kann?
Die Feuerwehr braucht, nach eingeganger Meldung des Feueralarms 80Min bis sie bei der Hütte ist.
Da wird nicht mehr viel zum löschen sein.

Wie sowas funktioniert, progge ich nicht auf einem PC mit Internet-Anbindung....

Was ich hier eigentlich wollte hat sich erledigt (s. Post #24)
 
Zuletzt bearbeitet von einem Moderator:
No Feedback ??? 😳 😳 😳 🙂🙂🙂
Dann Passt ja alles.
 
Zuletzt bearbeitet von einem Moderator:
Es hilft ja nicht, dass die ganze Welt weiss, dass meine Hütte brennt!
Wieso weiss es die ganze Welt? Das sind günstige Low-Bandwith Verbindungen, die aber auch verschlüsselt sein können (und müssen, sobald DSGVO ins Spiel kommt) und so...

Also 80 Minuten, bis die Feuerwehr da ist, ist wohl weniger in Deutschland ... aber auch mit automatischen Löschanlagen: Die garantieren keinen 100% Löscherfolg und daher sollte da auch dann entsprechende Hilfe angefordert werden....

Aber das muss man nicht vertiefen - das war ja nur ein Beispiel, dass so fast nichts mehr kostet, Systeme zu vernetzen. Computer ohne Netzwerk sind daher eher Nische.

Das war aber auch nur ein Punkt - denn der wichtige Punkt bezüglich der Technologien, die eigentlich für Web-Entwicklung gedacht waren, ist ja, dass dies eben nicht darauf beschränkt ist. So wie ElectronJS gibt es auch andere Frameworks für z.B. Apps.

Aber das muss man nicht weiter vertiefen - der Punkt bezüglich Entwicklung von Desktop Anwendungen ist ja nun genug vertieft worden.

Mein System ist LM22 Mate.
Somit kann (und will) ich die Geräte-Software vom Hersteller so nicht installierten.
Firefox meldet "Seite kann nicht gefunden werden" (Logisch: KEIN Internet, KEIN LAN, KEIN W-LAN)
Einfach nur USB thats all!
Wie wäre es, die Geräte Software auf einem anderen Gerät herunter zu laden und dann über USB Stick oder was auch immer dann aus das andere Gerät zu kopieren?

Und Thema Unkenntnis: Natürlich ist das erlaubt aber es ist auch erlaubt, darauf hin zu weisen.
 
Wie wäre es, die Geräte Software auf einem anderen Gerät herunter zu laden und dann über USB Stick oder was auch immer dann aus das andere Gerät zu kopieren?
Es gibt nicht wirklich eine brauchbare Gerätesoftware für LINUX!

Habs mit Wine versucht:
Aber habe Wine so eingestellt, dass es nicht auf Ports zugreifen kann, welche externe Komponenten ansprechen kann.
Ausser Maus und Tastatur (logisch)

Zudem nützen mir im Linux Informationen im Wine nur via Workaround.
Sprich, einen Drucker der im Wine installiert wurde, kann bei mir im LibreOffice (auf Linux installiert) nicht
gefunden werden (gem. meinen Einstellungen).

Selbts wenn ich die Herstellersoftware dann starte (läuft in Wein), dann wird dessen GUI gestartet mit der Meldung "Drucker kann nicht gefunden werden! Überprüfen Sie....... etc."
Logisch, Wein hat mit meinen Einstellungen keinen Zugriff auf das OS Linux.

Sowohl eine Sandbox oder eine VM funktionieren nicht so wie ich es will.
Mein kleines Etiketten-Programm läuft auf dem Installierte OS (hier Linux)
Zugriff auf VM ist unterbunden und auf einer Sandbox gehts schon gar nicht (was auch Sinn macht).

Und Thema Unkenntnis: Natürlich ist das erlaubt aber es ist auch erlaubt, darauf hin zu weisen.
Würde ich in den "Anfänger-Themen" kommunizieren wenn ich Kenntnis hätte? 😉
(Ist keine Hilfe, es frustiert nur)

OK. Das Thema ist für meine Bedürfnisse ausgereizt.
Kann als GELÖSST betrachtet werden. (Thread schlissen)

Vielen Dank
Richi
 
Zuletzt bearbeitet von einem Moderator:

Zurück
Oben