2017-03-29 9 views
0

Ich habe einen Code, wo ich viele "verschachtelte" Layouts habe. Border, Flow und in meinem Hauptprogramm habe ich einen GridBag. Ich füge Felder dynamisch zu einem Feld hinzu und sortiere sie so, dass jedes Element vertikal hinzugefügt wird, aber nicht nach oben oder unten geblättert wird. Ich schaute auf das Netz und fand etwas Ähnliches, aber das erlaubt mir nur, horizontal und nicht vertikal zu scrollen, wie ich es will. Dies ist mein Testcode, den ich schrieb:Mein JScrollPane scrollt nicht vertikal über mein JPanel

import java.awt.BorderLayout; 
import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.FlowLayout; 
import java.awt.Font; 

import javax.swing.BorderFactory; 
import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JPanel; 
import javax.swing.JScrollPane; 

public class Main { 

    public Main() { 
     JFrame frame = new JFrame("Blah"); 

     Font font = new Font("Sans-Serif", Font.BOLD, 30); 

     JPanel memoryPanel = new JPanel(); 
     memoryPanel.setLayout(new FlowLayout(FlowLayout.CENTER, 0, 0)); 
     //memoryPanel.setPreferredSize(new Dimension(80 * 4, 55 * 9)); 

     JScrollPane s = new JScrollPane(memoryPanel, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); 
     s.getViewport().setPreferredSize(new Dimension(80 * 4, 55 * 9)); 

     for (int i = 0; i <= 10; i++) { 

      JPanel nextPanel = new JPanel(); 
      nextPanel.setLayout(new BorderLayout()); 
      nextPanel.setBackground(Color.CYAN); 
      nextPanel.setForeground(Color.BLACK); 

      JPanel labelPanel = new JPanel(); 
      labelPanel.setLayout(new BorderLayout()); 

      JPanel buttonPanel = new JPanel(); 
      buttonPanel.setLayout(new FlowLayout(FlowLayout.TRAILING, 0, 0)); 

      JLabel label = new JLabel(); 
      label.setText("" + i); 
      label.setPreferredSize(new Dimension(80 * 4, 55)); 
      label.setHorizontalAlignment(JLabel.RIGHT); 
      label.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 5)); 

      JButton button1 = new JButton("A"); 
      JButton button2 = new JButton("B"); 
      JButton button3 = new JButton("C"); 

      label.setFont(font); 
      labelPanel.add(label); 

      buttonPanel.add(button1); 
      buttonPanel.add(button2); 
      buttonPanel.add(button3); 

      nextPanel.add(labelPanel, BorderLayout.PAGE_START); 
      nextPanel.add(buttonPanel, BorderLayout.PAGE_END); 

      memoryPanel.add(nextPanel, 0); 
      memoryPanel.revalidate(); 
      memoryPanel.repaint(); 
     } 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.add(s); 
     frame.setResizable(false); 
     frame.pack(); 
     frame.setLocationRelativeTo(null); 
     frame.setVisible(true); 
    } 

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

Mit dieser kommentierten Zeile zeigt es die horizontale Bildlaufleiste. Wenn es nicht kommentiert wird, zeigt es keine. Ich bin mir nicht sicher, ob ich die Layouts falsch verwende oder nicht, aber ich habe versucht, es für ein paar Stunden zu reparieren. Die Linie, die ich hinzufügte, war s.getViewport().setPreferredSize(new Dimension(80 * 4, 55 * 9));, die alles horizontal anstatt vertikal macht. Ich bin mir nicht sicher, wie ich das beheben kann. Vorschläge?

+1

's.getViewport () .setPreferredSize (neue Dimension (80 * 4, 55 * 9)); 'ist falsch zu versuchen und zu ändern. Das "Viewport" zeigt einen Teil der "Ansicht" an, seine Größe sollte eigentlich die des 'JScrollPane' sein (ohne die Scrollbalken). – MadProgrammer

+1

Ich würde auch' frame.setResizable (false); 'und' memoryPanel.setPreferredSize loswerden (neue Dimension (80 * 4, 55 * 9)); 'und lassen Sie das Fenster sich selbst um den Inhalt packen – MadProgrammer

Antwort

2

Beginnen Sie mit s.getViewport().setPreferredSize(new Dimension(80 * 4, 55 * 9)); loszuwerden. Sie möchten die Größe des Ansichts-Ports nicht ändern, es ist ein Container für Ihren Inhalt und fungiert als "Fenster", das den sichtbaren Teil der Komponente anzeigt.

ScrollPane

Als nächste von frame.setResizable(false); loszuwerden, wird dies nun ermöglicht Pack tatsächlich um den Inhalt aus dem Fenster zu packen. Da Sie eine FlowLayout verwenden, neigt dies dazu, das Fenster so breit wie den Bildschirm zu machen.

import java.awt.BorderLayout; 
import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.FlowLayout; 
import java.awt.Font; 
import javax.swing.BorderFactory; 
import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JPanel; 
import javax.swing.JScrollPane; 
import javax.swing.SwingUtilities; 

public class Main { 

    public Main() { 
     JFrame frame = new JFrame("Blah"); 

     Font font = new Font("Sans-Serif", Font.BOLD, 30); 

     JPanel memoryPanel = new JPanel(); 
     memoryPanel.setLayout(new FlowLayout(FlowLayout.CENTER, 0, 0)); 
     //memoryPanel.setPreferredSize(new Dimension(80 * 4, 55 * 9)); 

     JScrollPane s = new JScrollPane(memoryPanel, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); 
     //  s.getViewport().setPreferredSize(new Dimension(80 * 4, 55 * 9)); 

     for (int i = 0; i <= 10; i++) { 

      JPanel nextPanel = new JPanel(); 
      nextPanel.setLayout(new BorderLayout()); 
      nextPanel.setBackground(Color.CYAN); 
      nextPanel.setForeground(Color.BLACK); 

      JPanel labelPanel = new JPanel(); 
      labelPanel.setLayout(new BorderLayout()); 

      JPanel buttonPanel = new JPanel(); 
      buttonPanel.setLayout(new FlowLayout(FlowLayout.TRAILING, 0, 0)); 

      JLabel label = new JLabel(); 
      label.setText("" + i); 
      label.setPreferredSize(new Dimension(80 * 4, 55)); 
      label.setHorizontalAlignment(JLabel.RIGHT); 
      label.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 5)); 

      JButton button1 = new JButton("A"); 
      JButton button2 = new JButton("B"); 
      JButton button3 = new JButton("C"); 

      label.setFont(font); 
      labelPanel.add(label); 

      buttonPanel.add(button1); 
      buttonPanel.add(button2); 
      buttonPanel.add(button3); 

      nextPanel.add(labelPanel, BorderLayout.PAGE_START); 
      nextPanel.add(buttonPanel, BorderLayout.PAGE_END); 

      memoryPanel.add(nextPanel, 0); 
      memoryPanel.revalidate(); 
      memoryPanel.repaint(); 
     } 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.add(s); 
     //  frame.setResizable(false); 
     frame.pack(); 
     frame.setLocationRelativeTo(null); 
     frame.setVisible(true); 
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       new Main(); 
      } 
     }); 
    } 
} 

Wenn Sie die Größe des scrollbaren Ansichtsbereich beeinflussen wollen, dann müssen Sie eine benutzerdefinierte Klasse erstellen, die die Scrollable-Schnittstelle implementiert und das Rück entsprechenden Werte nach Ihren Bedürfnissen

+0

' frame.setResizable' hat nichts mit der Funktionalität von 'pack()' zu tun; es bestimmt lediglich, ob der Endbenutzer die Größe des Fensters ändern kann. – VGR

+0

@VGR Wirklich, also warum das Fenster Größe über die Größe meines Bildschirms hinaus und zeigte nicht die Bildlaufleisten, wenn es eingestellt war und wenn es nicht war, auf die Breite meines Bildschirms und zeigte die Bildlaufleisten. Ich vermeide 'setResizable', es verursacht mehr Probleme als es löst – MadProgrammer

+0

@VGR Mit' setResizable (false) 'ist die Framegröße '3524x110', ohne sie ist die Framegröße' 1920x110' - also würde ich sagen wir, 'setResizable' hat einen Effekt auf die Funktionsweise von' pack' – MadProgrammer

Verwandte Themen