2016-06-08 9 views
3

Ich kann nicht den Standard BorderFactory.createEmptyBorder funktioniert ordnungsgemäß in Java Swing.Java Swing rechten Rahmen funktioniert nicht auf Microsoft Windows

Ich versuchte es mit einer einfachen Java-App, die eine Spinner-Ansicht erstellt und einen leeren Rahmen um sie herum definiert. Die Umrandung wird überall mit Ausnahme der rechten Seite der Ansicht des Drehfelds angezeigt. aber das ist nur in Windows passiert, auf OSX funktioniert es wie vorgesehen.

Um die Verwendung eines Rahmens zu verdeutlichen: In meiner realen Anwendung habe ich eine sichtbare Grenze an der Außenseite des Spinner und dann möchte ich den Text im Inneren zentrieren. Ich fand die createCompoundBorder Eigenschaft sehr nützlich dafür.

import javax.swing.*; 
import java.awt.*; 
import javax.swing.border.Border; 

class HelloWorldSwing { 
    public static void main(String[] args) { 
     try { 
      UIManager.setLookAndFeel(
       UIManager.getSystemLookAndFeelClassName()); 
     } catch (Exception e) {} 

     Runnable guiCreator = new Runnable() { 
      public void run() { 
       JFrame fenster = new JFrame("Hallo Welt mit Swing"); 
       fenster.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

       SpinnerNumberModel model = new SpinnerNumberModel(1,1,9,1); 
       JSpinner spinner = new JSpinner(model); 

       JFormattedTextField textField = ((JSpinner.DefaultEditor)spinner.getEditor()).getTextField(); 
       textField.setOpaque(true); 
       // textField.setBackground(Color.); 

       spinner.setBorder(BorderFactory.createEmptyBorder(50, 100, 50, 100)); 

       spinner.setUI(new javax.swing.plaf.basic.BasicSpinnerUI() { 
        protected Component createNextButton() { 
         Component c = new JButton(); 
         c.setPreferredSize(new Dimension(0, 0)); 
         c.setFocusable(false); 
         return c; 
        } 

        protected Component createPreviousButton() { 
         Component c = new JButton(); 
         c.setPreferredSize(new Dimension(0, 0)); 
         c.setFocusable(false); 
         return c; 
        } 
       }); 
       spinner.setBackground(Color.LIGHT_GRAY); 
       fenster.add(spinner); 

       fenster.setSize(300, 200); 
       fenster.setVisible(true); 
      } 
     }; 

     SwingUtilities.invokeLater(guiCreator); 
    } 
} 

EDIT: Ich will nicht, eine Lösung zu finden, die ein weiteres UI-Element implementiert. Dies wäre eine einfache und einfache Lösung (Danke an Andrew Thompson). Der Grund ist, dass es nur ein kleines Projekt ist, bei dem ich auf diesen Fehler gestoßen bin. In kleinen Projekten möchte ich meistens einen sauberen und gut aussehenden Code, was bedeutet, dass solche Fehler behoben werden, indem versucht wird, den kaputten Code zu reparieren und nicht, indem man eine Abhilfe schafft.

Vielen Dank im Voraus

+0

Welche Version (en) von Windows? –

+0

Dieser Code deklariert nie eine Variable namens "fenster". (Vermutlich ein JFrame?) – FredK

+0

sorry. Versehentlich gelöscht, während einige ungenutzte Kommentare entfernt wurden. –

Antwort

2

Es sieht aus wie ein JSpinner einen benutzerdefinierten Layout-Manager verwendet, und ist die Grenze nicht richtig handhaben.

Ich habe Ihren Code geändert, um den Schaltflächen die Breite der rechten Kante des Rahmens minus 1 zu geben. Ich nehme an, dass der Layoutmanager eine Lücke von 1 Pixel zwischen der Kante des Textfelds und der Schaltfläche belässt.

Scheint unter Windows zu arbeiten, aber es könnte OSX versauen?

import javax.swing.*; 
import java.awt.*; 
import javax.swing.border.Border; 

class HelloWorldSwing { 
    public static void main(String[] args) { 
     try { 
      UIManager.setLookAndFeel(
       UIManager.getSystemLookAndFeelClassName()); 
     } catch (Exception e) {} 

     Runnable guiCreator = new Runnable() { 
      public void run() { 
       JFrame fenster = new JFrame("Hallo Welt mit Swing"); 
       fenster.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

       SpinnerNumberModel model = new SpinnerNumberModel(1,1,9,1); 
       JSpinner spinner = new JSpinner(model); 

       JFormattedTextField textField = ((JSpinner.DefaultEditor)spinner.getEditor()).getTextField(); 
       textField.setOpaque(true); 
       // textField.setBackground(Color.); 

       spinner.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 0)); 

       spinner.setUI(new javax.swing.plaf.basic.BasicSpinnerUI() { 
        protected Component createNextButton() { 
         Component c = new JButton(); 
         c.setPreferredSize(new Dimension(9, 0)); 
         c.setVisible(false); 
         return c; 
        } 

        protected Component createPreviousButton() { 
         Component c = new JButton(); 
         c.setPreferredSize(new Dimension(9, 0)); 
         c.setVisible(false); 
         return c; 
        } 
       }); 
       spinner.setBackground(Color.LIGHT_GRAY); 
       fenster.setLayout(new FlowLayout()); 
       fenster.add(spinner); 

       fenster.setSize(300, 200); 
       fenster.setVisible(true); 
      } 
     }; 

     SwingUtilities.invokeLater(guiCreator); 
    } 
} 

Die andere Lösung besteht darin, kein JSpinner zu verwenden. Sie könnten einfach ein JTextField verwenden und eine benutzerdefinierte Aktion für die Pfeile nach oben/unten schreiben. Ein bisschen mehr Arbeit, aber es wird auf allen Plattformen funktionieren.

Auch da Sie sich Sorgen um zusätzliche Komponenten zu machen scheint, wird dies in dieser Hinsicht viel effizienter sein. Der Jspinner ist selbst eine komplexe Komponente und das JFormattedTextField ist weitaus komplexer als ein einfaches JTextField.

+0

danke. Funktioniert perfekt –