2012-10-11 17 views
6

Sto costruendo un'applicazione che consisterà di pochi pannelli a schede. Su ognuna di esse, vorrei mettere set di componenti separati l'uno dall'altro dai confini. Si sarebbe simile:Come circondare i componenti Java Swing con il bordo?

|- Titled Border 1 --- 

[JTextField] [JComboBox] [JTextField] [JComboBox] 

|-------- 

|- Titled Border 2 --- 

[JTextField] [JComboBox] [JTextField] [JComboBox] 

|-------- 

... and so forth. 

Quando ho cercato di aggiungere semplicemente nuovo confine, Intitolato Border 2, al pannello, è stato aggiunto e ha riguardato il primo lasciando componenti sulla parte superiore però. In alcuni esempi ho visto molti JPanel definiti all'interno di un frame e ogni pannello aveva il suo bordo. Potrebbe funzionare nel mio caso, ma come aggiungere questi pannelli per essere visualizzati all'interno di una scheda?

Uno dei tutorial di Oracle mostra esattamente un riquadro con schede con la demo di molti tipi di bordi. Quando ho provato a modificarlo e inserire un componente, è apparso tra due bordi invece di essere circondato. Ed era un'altra opzione che non ha avuto successo per me.

La seconda cosa è che non utilizzo alcun gestore di layout, le posizioni dei componenti sono fisse e sinceramente manterrei questa impostazione. O forse si consiglia di utilizzare un gestore di layout in questo caso specifico?

Avete qualche suggerimento su come risolvere questo problema?

Edit: sembra che io non sono ancora permesso di allegare uno screenshot, ma ecco la parte di codice di prendersi cura di visualizzare i confini:

lenMicro = new JPanel(); 
    lenMicro.setLayout(null); 

    bGreyLine = BorderFactory.createLineBorder(Color.GRAY, 1, true); 
    bTitled1 = BorderFactory.createTitledBorder(bGreyLine, "Length (1/2)", TitledBorder.LEFT, TitledBorder.TOP); 
    lenMicro.setBorder(bTitled1); 
    bTitled2 = BorderFactory.createTitledBorder(bGreyLine, "Length (2/2)", TitledBorder.LEFT, TitledBorder.TOP); 
    lenMicro.setBorder(bTitled2); 

Il confine dal titolo "Lunghezza (2/2)" viene visualizzato quando le ultime due righe non sono commentate.

+3

direi - utilizzare LayoutManager nel 99,99% dei casi. L'unica eccezione potrebbe essere se fornisci alcuni oggetti casuali, ad es. forme di disegno dell'utente. – StanislavL

+0

Puoi allegare alcuni screenshot invece di descrivere la situazione? –

+2

L'API dice di mettere il bordo sul contenitore che contiene il componente. –

risposta

15

Quando si utilizza Absolute Positioning, è necessario fornire la posizione per ogni singolo componente, che diventerà parte della vista. Quindi, senza guardare esattamente quello che stai facendo, è difficile prevedere dove esattamente le cose stiano andando male. Anche se l'utilizzo di Layout Managers rimuoverà questo grosso carico dalle spalle per quanto riguarda il posizionamento di diversi componenti nella vista.

Inoltre, è necessario impostare il bordo per il rispettivo componente. Quindi, in nessun modo posso supporre che tu abbia aggiunto un componente e sia apparso tra due confini (anche se considerando il fatto che stai usando Posizionamento assoluto, potresti aver dato le coordinate sbagliate per il componente indicato nella vista). Si prega di dare un'occhiata a questo codice di esempio, che la forza può aiutare un po 'in questa direzione:

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

public class BorderExample 
{ 
    private JPanel topPanel; 
    private JPanel centerPanel; 
    private JPanel bottomPanel; 
    private int hgap; 
    private int vgap; 
    private JTextField tfield1, tfield2; 
    private JComboBox cbox1, cbox2; 
    private String[] data = {"One", "Two"}; 

    public BorderExample() 
    { 
     hgap = 5; 
     vgap = 5; 
    } 

    private void displayGUI() 
    { 
     JFrame frame = new JFrame("Border Example"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

     JPanel contentPane = new JPanel(); 
     contentPane.setOpaque(true); 
     contentPane.setBackground(Color.WHITE); 
     contentPane.setBorder(
      BorderFactory.createEmptyBorder(hgap, hgap, hgap, hgap)); 
     contentPane.setLayout(new BorderLayout(hgap, vgap)); 

     topPanel = new JPanel(); 
     topPanel.setOpaque(true); 
     topPanel.setBackground(Color.WHITE); 
     topPanel.setBorder(
      BorderFactory.createTitledBorder("Top Panel")); 
     tfield1 = new JTextField(10); 
     tfield1.setBorder(
      BorderFactory.createTitledBorder(
      BorderFactory.createEtchedBorder(
        EtchedBorder.RAISED, Color.GRAY 
        , Color.DARK_GRAY), "JTextField")); 
     JPanel comboPanel = new JPanel();   
     cbox1 = new JComboBox(data); 
     cbox1.setBorder(
      BorderFactory.createTitledBorder("JComboBox")); 
     topPanel.add(tfield1); 
     topPanel.add(cbox1); 

     centerPanel = new JPanel(); 
     centerPanel.setOpaque(true); 
     centerPanel.setBackground(Color.WHITE); 
     centerPanel.setBorder(
      BorderFactory.createTitledBorder("Center Panel")); 
     tfield2 = new JTextField(10); 
     tfield2.setBorder(
      BorderFactory.createLoweredBevelBorder()); 
     cbox2 = new JComboBox(data); 
     cbox2.setBorder(
      BorderFactory.createRaisedBevelBorder()); 
     centerPanel.add(tfield2); 
     centerPanel.add(cbox2); 

     bottomPanel = new JPanel(); 
     bottomPanel.setOpaque(true); 
     bottomPanel.setBackground(Color.WHITE); 
     bottomPanel.setBorder(
      BorderFactory.createTitledBorder("Center Panel")); 

     contentPane.add(topPanel, BorderLayout.PAGE_START); 
     contentPane.add(centerPanel, BorderLayout.CENTER); 
     contentPane.add(bottomPanel, BorderLayout.PAGE_END); 

     frame.setContentPane(contentPane); 
     frame.pack(); 
     frame.setLocationByPlatform(true); 
     frame.setVisible(true); 
    } 

    public static void main(String... args) 
    { 
     SwingUtilities.invokeLater(new Runnable() 
     { 
      @Override 
      public void run() 
      { 
       new BorderExample().displayGUI(); 
      } 
     }); 
    } 
} 

Qui è l'uscita dello stesso:

BORDER_EXAMPLE

+0

Grazie mille! Mi ha aiutato a capire come stanno andando le cose in questa faccenda. Ho deciso di utilizzare un gestore di layout, GridBagLayout, e ora ho a che fare con le impostazioni di esso. Quando ho finito, pubblicherò le parti più rilevanti del codice. – AbreQueVoy

+0

Sicuro di chiedere qualsiasi cosa, che potrebbe darti dei problemi, i layout sono sempre buoni. Per il resto, SEI PIÙ BENVENUTO e TIENI SORRIDENTE :-) Un [SSCCE] (http://sscce.org/) su cui lavorare, sarà ancora molto apprezzato –

2

OK, quindi questo risolve un gran parte delle mie preoccupazioni per quanto riguarda l'utilizzo di layout manager e l'aggiunta di bordi per gruppi di componenti:

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

public class TestingGround extends JFrame { 

private JTextField tLenUnit, tLenResult, tAreUnit, tAreResult; 
private JComboBox<String> cLenInUnit, cLenOutUnit, cAreInUnit, cAreOutUnit; 
private JPanel lenMicro, lenMicro1, lenMicro2, lenNormal, lenMacro, area, volume; 
private Border bGreyLine, bTitled1, bTitled2; 

private TestingGround() { 

    setTitle("Testing Ground for an Application"); 
    setVisible(true); 
    setResizable(true); 
    setLocationRelativeTo(null); 

    try { 
     UIManager.setLookAndFeel("javax.swing.plaf.nimbus.NimbusLookAndFeel"); 
    } catch (ClassNotFoundException e) { 
     e.printStackTrace(); 
    } catch (InstantiationException e) { 
     e.printStackTrace(); 
    } catch (IllegalAccessException e) { 
     e.printStackTrace(); 
    } catch (UnsupportedLookAndFeelException e) { 
     e.printStackTrace(); 
    } 

    lenMicro = new JPanel(); 
    lenMicro.setLayout(new GridBagLayout()); 

    lenMicro1 = new JPanel(); 
    lenMicro1.setLayout(new GridBagLayout()); 

    bGreyLine = BorderFactory.createLineBorder(Color.LIGHT_GRAY, 1, true); 
    bTitled1 = BorderFactory.createTitledBorder(bGreyLine, "Length", TitledBorder.LEFT, TitledBorder.TOP); 
    lenMicro1.setBorder(bTitled1); 

    tLenUnit = new JTextField("0.0"); 
    tLenUnit.setColumns(10); 
    lenMicro1.add(tLenUnit, new GBC(0, 0, 2, 1).setAnchor(GBC.WEST).setInsets(5, 5, 5, 5)); 

    cLenInUnit = new JComboBox<String>(); 
    cLenInUnit.addItem(""); 
    cLenInUnit.addItem("First"); 
    cLenInUnit.addItem("Second"); 
    cLenInUnit.setSelectedIndex(0); 
    cLenInUnit.setPreferredSize(new Dimension(120, 25)); 
    lenMicro1.add(cLenInUnit, new GBC(2, 0, 3, 1)); 

    tLenResult = new JTextField(""); 
    tLenResult.setColumns(10); 
    lenMicro1.add(tLenResult, new GBC(5, 0, 2, 1).setInsets(5, 5, 5, 5)); 

    cLenOutUnit = new JComboBox<String>(); 
    cLenOutUnit.addItem("First"); 
    cLenOutUnit.addItem("Second"); 
    cLenOutUnit.setSelectedIndex(1); 
    cLenOutUnit.setPreferredSize(new Dimension(120, 25)); 
    lenMicro1.add(cLenOutUnit, new GBC(7, 0, 1, 1)); 

    // Area part: 

    lenMicro2 = new JPanel(); 
    lenMicro2.setLayout(new GridBagLayout()); 

    bTitled2 = BorderFactory.createTitledBorder(bGreyLine, "Area", TitledBorder.LEFT, TitledBorder.TOP); 
    lenMicro2.setBorder(bTitled2); 

    tAreUnit = new JTextField("0.0"); 
    tAreUnit.setColumns(10); 
    lenMicro2.add(tAreUnit, new GBC(0, 1, 2, 1).setAnchor(GBC.WEST).setInsets(5, 5, 5, 5)); 

    cAreInUnit = new JComboBox<String>(); 
    cAreInUnit.addItem(""); 
    cAreInUnit.addItem("One sqm"); 
    cAreInUnit.addItem("Two sqm"); 
    cAreInUnit.setSelectedIndex(0); 
    cAreInUnit.setPreferredSize(new Dimension(120, 25)); 
    lenMicro2.add(cAreInUnit, new GBC(2, 1, 3, 1)); 

    tAreResult = new JTextField(""); 
    tAreResult.setColumns(10); 
    lenMicro2.add(tAreResult, new GBC(5, 1, 2, 1).setInsets(5, 5, 5, 5)); 

    cAreOutUnit = new JComboBox<String>(); 
    cAreOutUnit.addItem("One sqm"); 
    cAreOutUnit.addItem("Two sqm"); 
    cAreOutUnit.setSelectedIndex(1); 
    cAreOutUnit.setPreferredSize(new Dimension(120, 25)); 
    lenMicro2.add(cAreOutUnit, new GBC(7, 1, 1, 1)); 

    // Joining all lenMicroX panels into one: 

    lenMicro.add(lenMicro1, new GBC(0, 0, 8, 1).setAnchor(GBC.FIRST_LINE_START).setInsets(5, 5, 5, 5).setIpad(10, 10)); 
    lenMicro.add(lenMicro2, new GBC(0, 1, 8, 1).setAnchor(GBC.LINE_START).setInsets(5, 5, 5, 5).setIpad(10, 10)); 

    volume = new JPanel(); 
    volume.setLayout(null); 

    // Panel definition --begin: 

    JTabbedPane tPane = new JTabbedPane(); 

    tPane.addTab("Length & Area", null, lenMicro, "Length & Area units"); 
    tPane.addTab("Volume", null, volume, "Volume units"); 
    add(tPane); 

    // Panel --end. 
} 

public static void main(String[] args) { 

    TestingGround app = new TestingGround(); 
    app.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    app.pack(); 
    app.setVisible(true); 

} 

} 

GridBagConstraints classe helper è preso fro m Cay Horstmann e Gary Cornell Java Java e possono essere trovati qui: http://www.horstmann.com/articles/GBC.java.

Sono riuscito a capire dall'esempio di Gagandeep che i pannelli possono essere sovrapposti, chiamiamolo un pannello madre. In questo modo, ciascuno dei pannelli figlio può avere il proprio bordo.

Seconda cosa: ho deciso di utilizzare GridBagLayout, in quanto sembra essere il più preciso da utilizzare in questo e in altri miei progetti.Beh, devo ancora imparare molto su questo (per esempio, per rendere i componenti allineati ad alcune linee ;-) [modifica: ha appena aggiunto setPreferredSize() a JComboBoxes; rende il layout più bello ;-)]).

Grazie a tutti per l'aiuto e suggerimenti preziosi!

The application after correction.

+1

Solo un consiglio, usa sempre le chiamate come ** frame.setVisible (true/false) **, dopo aver aggiunto tutto a 'JFrame', non prima. In questo modo si presenta alla vista, una volta che ha realizzato la sua dimensione. Come fatto da te, potrebbe a volte dare risultati anomali, chiamando la proprietà visibile molto prima che il frame abbia effettivamente calcolato la sua dimensione. +1 anche se per lo sforzo che hai dato in questo :-) –

+1

OK, grazie per il consiglio! (Dovrò parlare con la mia insegnante allora, ah ah :-)) – AbreQueVoy

Problemi correlati