2017-07-10 5 views
1

Ich bin ziemlich neu in Java und ich bin bei einem vollständigen Verlust. Ich versuche ein einfaches Programm zu erstellen, das einen Kreis zeichnet und seine Eigenschaften auf dem Bildschirm ausgibt. Funktionell funktioniert das Programm gut, aber das Layout der JPanels ist deaktiviert. Aus irgendeinem Grund gibt es eine Lücke zwischen dem JPanel, das die Schaltfläche "Draw Me" enthält und der JPanel, die den Kreis enthält. Auch wenn ich die Höhe des Programms verändere, verschwindet die Lücke nicht. Ebenso sind die Etiketten innerhalb des Programms nicht nach links ausgerichtet, sie sitzen aus irgendeinem seltsamen Grund dezentriert, das Entfernen der Grenze scheint nicht zu helfen. Ich bin fest ...Ausrichtung von JPanels

import javax.swing.*; 
import java.awt.*; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.awt.geom.Ellipse2D; 

public class MainPanel extends JPanel { 
private JPanel userHelpSubPanel; 
private JPanel inputSubPanel; 
private JPanel buttonSubPanel; 
private JPanel drawSubPanel; 
private JPanel resultsSubPanel; 
private JLabel userHelpLabel; 
private JLabel diameterLabel; 
private JLabel circumferenceLabel; 
private JLabel areaLabel; 
private JButton drawButton; 
private JTextField inputTextField; 
private float radius; 

public MainPanel() { 
    radius = 0; 

    setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); 

    userHelpSubPanel = new JPanel(new FlowLayout(FlowLayout.LEFT)); 

    inputSubPanel = new JPanel(); 
    inputSubPanel.setLayout(new BoxLayout(inputSubPanel, BoxLayout.Y_AXIS)); 

    drawSubPanel = new JPanel() { 
     @Override 
     public void paintComponent(Graphics g) { 
      super.paintComponent(g); 

      Graphics2D g2d = (Graphics2D) g; 

      g2d.draw(new Ellipse2D.Double(150, 20, radius * 2, radius * 2)); 
     } 
    }; 

    resultsSubPanel = new JPanel(); 
    resultsSubPanel.setLayout(new BoxLayout(resultsSubPanel, BoxLayout.Y_AXIS)); 

    buttonSubPanel = new JPanel(); 

    userHelpLabel = new JLabel(); 
    userHelpLabel.setText("Enter the radius of the ellipse: "); 

    inputTextField = new JTextField(); 
    inputTextField.setMaximumSize(new Dimension(Integer.MAX_VALUE, inputTextField.getPreferredSize().height)); 

    drawButton = new JButton("Draw Me"); 
    drawButton.addActionListener(new ActionListener() { 
     @Override 
     public void actionPerformed(ActionEvent e) { 
      MainPanel.this.radius = Float.parseFloat(inputTextField.getText()); 

      diameterLabel.setText(String.format("Diameter: %.1f", 2 * radius)); 
      circumferenceLabel.setText(String.format("Circumference: %.1f", 2 * Math.PI * radius)); 
      areaLabel.setText(String.format("Area: %.1f", Math.PI * Math.pow(radius, 2))); 

      drawSubPanel.repaint(); 
     } 
    }); 

    circumferenceLabel = new JLabel("Circumference: N/A"); 
    diameterLabel = new JLabel("Diameter: N/A"); 
    areaLabel = new JLabel("Area: N/A"); 

    userHelpSubPanel.add(userHelpLabel); 
    inputSubPanel.add(inputTextField); 
    buttonSubPanel.add(drawButton); 
    resultsSubPanel.add(diameterLabel); 
    resultsSubPanel.add(circumferenceLabel); 
    resultsSubPanel.add(areaLabel); 

    add(userHelpLabel); 
    add(inputSubPanel); 
    add(buttonSubPanel); 
    add(drawSubPanel); 
    add(resultsSubPanel); 
} 
} 

Und hier ist, wie es aussieht ....

https://i.stack.imgur.com/PEHVE.png

+3

Verwenden Sie GridBagLayout - es ist am besten für die Aufgabe, die Sie haben. https://docs.oracle.com/javase/tutorial/uiswing/layout/gridbag.html – mko

Antwort

1

BoxLayout die Minimal- und Maximalgrößen einer Komponente respektieren. Wenn im Rahmen mehr Platz vorhanden ist, erhalten die Paneele mehr Platz.

Die Lösung ist es, das Verfahren getMaximumSize() der benutzerdefinierten Platte zu überschreiben, die bevorzugte Größe der Platte zurückzukehren.

Jede Swing-Komponente ist responsibile für seine eigene bevorzugte Größe determiningin. Das würde bedeuten, dass Sie auch die getPreferredSize() des Panels überschreiben müssen, in dem Sie die benutzerdefinierte Bemalung durchführen. Die bevorzugte Größe würde auf der Größe/Position des Ovals basieren, das Sie zeichnen.

-3

Eine einfache Lösung für diese Probleme ist Panels (relevant ist) eine leere Grenze zu geben und dann die spezifische Richtung zu reduzieren, die zu groß ist:

// this example reduces the top of your circle panel. 
drawSubPanel.setBorder(new EmptyBorder(-100, 0, 0, 0)); 

Offensichtlich ist dies nicht die Wurzel des Problems und ist nicht optimal, aber es sollte den Trick machen.

+2

(1-) Dies ist nicht die Lösung. Die Größe des Bedienfelds ändert sich dynamisch, wenn die Größe des Rahmens geändert wird. Das Codieren eines Wertes in einem EmptyBorder ist einfach nicht die Lösung des Problems. Verwenden Sie Swing so, wie es entworfen wurde. – camickr

+0

Kannst du lesen? Ganz sicher nicht. Du liegst auf so vielen Ebenen falsch. Vielleicht von deinem Stuhl steigen und ihm eine Antwort geben, dann Besserwisser? Komisch, du planst, weniger Zeit als ich mit dieser Frage zu verbringen, und doch lehnst du dich zurück und kritisierst, als ob du meinen Haftungsausschluss komplett verpasst hättest. – Daedric