2016-01-21 145 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+以及您的答案。 –