2016-01-21 144 views
0

出於某種原因,我的滾動條出現,但它不起作用。假設發生的事情是使用滾動條滾動瀏覽textarea的文本。有人能解釋爲什麼這不起作用嗎?滾動條JTextarea無效

import java.io.*; 
import java.awt.event.*; 
import java.awt.*; 
import javax.swing.*; 

public class App extends JFrame{ 
    private JPanel paneel; 

    public App(){ 
     paneel = new AppPaneel(); 
     setContentPane(paneel); 
    } 

    public static void main(String args[]){ 
     JFrame frame = new App(); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.setSize(400, 400); 
     frame.setTitle("Auto Clicker"); 
     frame.setVisible(true); 
    } 
} 

class AppPaneel extends JPanel{ 
    private JTextField delayField, xLocation, yLocation; 
    private JTextArea listArea; 
    private JButton addButton, saveButton, runButton; 
    private JScrollPane scroll; 

    public AppPaneel(){ 
     setLayout(null); 

     delayField = new JTextField(); 
     delayField.setBounds(10, 10, 85, 25); 
     delayField.setText("delay in ms"); 

     xLocation = new JTextField(); 
     xLocation.setBounds(105, 10, 85, 25); 
     xLocation.setText("X position"); 

     yLocation = new JTextField(); 
     yLocation.setBounds(200, 10, 85, 25); 
     yLocation.setText("Y position"); 

     addButton = new JButton("Add"); 
     addButton.setBounds(295, 10, 75, 24); 
     addButton.addActionListener(new AddHandler()); 

     listArea = new JTextArea(); 
     listArea.setBounds(10, 45, 360, 180); 
     scroll = new JScrollPane(listArea); 
     scroll.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS); 
     scroll.setBounds(370, 45, 20, 180); 

     saveButton = new JButton("Save"); 
     saveButton.setBounds(10, 230, 85, 24); 

     runButton = new JButton("Run (F1)"); 
     runButton.setBounds(105, 230, 85, 24); 
     runButton.addActionListener(new RunHandler()); 

     add(delayField); 
     add(xLocation); 
     add(yLocation); 
     add(addButton); 
     add(listArea); 
     add(saveButton); 
     add(runButton); 
     add(scroll); 
    } 

    class AddHandler implements ActionListener{ 
     public void actionPerformed(ActionEvent a){ 
      listArea.setText(listArea.getText() + delayField.getText() + ",  " + xLocation.getText() + ", " + yLocation.getText() + ", " + "click;" + "\n"); 
     } 
    } 

    class RunHandler implements ActionListener{ 
     private Robot bot; 
     private String text; 
     int foo = Integer.parseInt("1234"); 
     public void actionPerformed(ActionEvent b) { 
      try{ 
       text = listArea.getText(); 
       bot = new Robot(); 
       for(String line : text.split("\\n")){ 
       int delay = Integer.parseInt((line.substring(0, 4))); 
       int xpos = Integer.parseInt((line.substring(6, 10))); 
       int ypos = Integer.parseInt((line.substring(12, 16))); 
       bot.mouseMove(xpos, ypos); 
       Thread.sleep(delay); 
       bot.mousePress(InputEvent.BUTTON1_MASK); 
       bot.mouseRelease(InputEvent.BUTTON1_MASK); 
       } 
      } 
      catch (AWTException | InterruptedException e){ 
       e.printStackTrace(); 
      } 
     } 
    } 
} 

回答

3

不要使用null佈局和setBounds,因爲它會搞亂你的程序。我們告訴人們一次又一次沒有一個理由這樣做 - 通過設置JTextArea中的束縛你限制其大小,以便當它需要也不會增長。解決方案一如既往 - 學習和使用佈局管理器。設置JTextArea的列和行屬性,但不是其邊界,大小或首選大小。

下不這樣做:Thread.sleep(delay);在Swing應用程序,因爲它會把整個應用程序睡覺。使用搖擺計時器代替任何延遲。這些教程可以幫助你使用它。

對於非功能佈局例如:

import java.awt.BorderLayout; 
import java.awt.GridLayout; 
import javax.swing.*; 

@SuppressWarnings("serial") 
public class App2 extends JPanel { 
    private static final int GAP = 5; 
    private JTextField textField1 = new JTextField(GAP); 
    private JTextField textField2 = new JTextField(GAP); 
    private JTextField textField3 = new JTextField(GAP); 
    private JTextArea textArea = new JTextArea(15, 30); 

    public App2() { 
     JPanel topPanel = new JPanel(new GridLayout(1, 0, GAP, GAP)); 
     topPanel.add(textField1); 
     topPanel.add(textField2); 
     topPanel.add(textField3); 
     topPanel.add(new JButton("Add")); 

     textArea.setWrapStyleWord(true); 
     textArea.setLineWrap(true); 
     JScrollPane scrollPane = new JScrollPane(textArea); 
     scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); 

     JPanel bottomPanel = new JPanel(new GridLayout(1, 0, GAP, GAP)); 
     bottomPanel.add(new JButton("Save")); 
     bottomPanel.add(new JButton("Run (F1)")); 
     bottomPanel.add(new JLabel("")); 
     bottomPanel.add(new JLabel("")); 

     setBorder(BorderFactory.createEmptyBorder(GAP, GAP, GAP, GAP)); 
     setLayout(new BorderLayout(GAP, GAP)); 
     add(topPanel, BorderLayout.PAGE_START); 
     add(scrollPane, BorderLayout.CENTER); 
     add(bottomPanel, BorderLayout.PAGE_END); 
    } 

    private static void createAndShowGui() { 
     JFrame frame = new JFrame("Auto Clicker"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.getContentPane().add(new App2()); 
     frame.pack(); 
     frame.setLocationRelativeTo(null); 
     frame.setVisible(true); 
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 
      public void run() { 
       createAndShowGui(); 
      } 
     }); 
    } 
} 
+0

(1+)爲更好的解決方案。 – camickr

+0

@camickr:謝謝,但我將它定義爲社區wiki的答案,因爲它讓我重複自己的廣告 - 「不要使用空白布局,因爲你只是在搞砸自己」 - 而且它似乎沒有什麼好處。這些人不斷地發佈相同的問題,而不是去搜索或閱讀過去的類似問題,所以他們註定要重複同樣的錯誤。此刻感覺非常沮喪。 –

+0

完全同意。我一直想知道他們在哪裏找到所有不好的示例代碼:(十多年來(我一直在各種論壇上),我們一直在推動佈局管理器。爲什麼人們不能從Swing教程中的一個簡單示例開始,這是我開始學習Swing時所做的第一件事情:)該API提供了該教程的鏈接。不要人們閱讀API嗎?令人沮喪的... – camickr

2

你的整個做法是錯誤的。您不應該使用空佈局。例如:

scroll.setBounds(370, 45, 20, 180); 

您將寬度設置爲20.那麼您如何期待文本區域以20像素顯示?這是使用setBounds(...)的問題,你使用的隨機數沒有意義。讓佈局經理完成它的工作。另外:

add(listArea); 

問題是組件只能有一個父組件。您最初創建的JScrollPane的文本區域是正確的。

但你直接添加文本區域,從滾動窗格使滾動面板將不再起作用刪除它的框架。

擺脫這種說法的,只是添加滾動窗格的框架。

不過,我不建議你使用它作爲您的最終解決方案。我只想提到當前的問題,所以您希望瞭解使用佈局管理器的好處,並且不要再嘗試共享組件。

正確的解決方案是使用佈局管理器爲已通過「社區維基」建議。然後佈局管理器將確定每個組件的大小和位置,因此您無需擔心正確計算像素值。

+0

和1+以及您的答案。 –