Java 滚动条未与JTextArea一起出现
好的,我最近制作了一个java控制台应用程序,它可以强制输入你的密码,所以现在我正在开发一个类似的应用程序,但是有一个gui。 所以我有所有的代码和它的运行,但出于某种原因,我添加到文本区域的滚动条没有出现,当我运行程序时,我既没有得到滚动条,也没有得到文本区域。 请告诉我哪里出了问题,帮我解决这个问题Java 滚动条未与JTextArea一起出现,java,swing,jscrollpane,jtextarea,Java,Swing,Jscrollpane,Jtextarea,好的,我最近制作了一个java控制台应用程序,它可以强制输入你的密码,所以现在我正在开发一个类似的应用程序,但是有一个gui。 所以我有所有的代码和它的运行,但出于某种原因,我添加到文本区域的滚动条没有出现,当我运行程序时,我既没有得到滚动条,也没有得到文本区域。 请告诉我哪里出了问题,帮我解决这个问题 package swinggui; import javax.swing.*; import java.util.*; import java.awt.*; import java.awt.e
package swinggui;
import javax.swing.*;
import java.util.*;
import java.awt.*;
import java.awt.event.*;
public class BruteForce {
static JFrame frameObject;
static JPanel panelObject;
JLabel lblPassword;
JTextField txtPassword;
JTextArea txtStatus;
JScrollPane scrollbar;
JButton btn;
BruteForce() {
panelObject = new JPanel();
frameObject.getContentPane().add(panelObject);
panelObject.setLayout(null);
txtStatus = new JTextArea("Status: ");
txtStatus.setBounds(10,95,260,160);
panelObject.add(txtStatus);
lblPassword = new JLabel("Password: ");
txtPassword = new JTextField();
Font dialog = new Font("Dialog", Font.PLAIN, 14);
lblPassword.setBounds(10,10,100,30);
lblPassword.setFont(dialog);
panelObject.add(lblPassword);
txtPassword.setBounds(80,10,190,30);
panelObject.add(txtPassword);
scrollbar = new JScrollPane(txtStatus);
panelObject.add(scrollbar);
btn = new JButton("Test Password Strength");
btn.setBounds(10,50,260,30);
panelObject.add(btn);
btn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
int password = Integer.parseInt(txtPassword.getText());
int guess_password = 0;
while(guess_password != password) {
txtStatus.append("\n [+] Password Attempt: " + guess_password);
guess_password = guess_password + 1;
}
if(guess_password == password) {
txtStatus.append("\n \n [-] Password Found: " + guess_password);
}
}
});
}
public static void main(String[] args) throws Exception {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
frameObject = new JFrame("Brute Force Tool");
frameObject.setVisible(true);
frameObject.setSize(300,300);
frameObject.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
BruteForce gui = new BruteForce();
}
}
请告诉我哪里出了问题,并更正我的代码。
我们将提前感谢您的帮助。首先有一个重要提示:不要使用空布局。请学习所有标准并使用它们填充您的UI。您还可以使用一些第三方布局管理器,如MigLayout或FormLayout(使用Google查找它们)。这些管理者往往比标准更优秀 为什么它比空布局更好?因为JavaUI是跨平台的,有些组件在不同的OSs上可能需要不同的大小。当用户使用某些操作系统功能(如字体缩放)时,也会发生同样的情况。布局管理器还定义了调整大小行为(当用户更改窗口大小时应发生的情况) 这是您的代码的正确版本(无布局管理器更改)
您确实意识到,如果您提供一个整数密码值(如55673),并且在循环中一次遍历一个值,那么您不需要应用程序来确定访问该密码的尝试次数(55673次迭代)。我们将把它记下来作为一个例子/ 在我看来,您的特定项目有许多问题需要注意: 为了简化编码,请设置BruteForce类,使其扩展JFrame:
公共类BruteForce扩展javax.swing.JFrame{
。您不需要静态JFrame变量(frameObject),它会稍微清理一些东西
从main()方法中取出所有与JFrame相关的代码。改为在初始化方法中进行JFrame设置。在我看来,如果您有:
public static void main(String[] args) throws Exception {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
/* Create and display the form */
java.awt.EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
new BruteForce().setVisible(true);
}
});
}
您的初始化方法可能如下所示:
private void initializeComponents() {
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
setTitle("Brute Force Tool");
setResizable(false);
setAlwaysOnTop(true);
// Size the Form
// Slightly different from original size since
// form has been made non-resizable. Makes the
// form more uniformed.
setPreferredSize(new Dimension(285, 325));
setSize(getPreferredSize());
// Center Form to screen. Should always be after sizing
setLocationRelativeTo(null);
panelObject = new JPanel();
panelObject.setLayout(null);
// Password Box Label
Font dialog = new Font("Dialog", Font.PLAIN, 14);
lblPassword = new JLabel("Password: ");
lblPassword.setBounds(10, 10, 100, 30);
lblPassword.setFont(dialog);
panelObject.add(lblPassword);
// Password Entry Text Field
txtPassword = new JTextField();
txtPassword.setBounds(80, 10, 190, 30);
panelObject.add(txtPassword);
// Text Area with Scroll Pane to display
// Brute Force process.
txtStatus = new JTextArea("Status: ");
scrollbar = new JScrollPane(txtStatus);
scrollbar.setBounds(10, 125, 260, 160);
panelObject.add(scrollbar);
// Button to start Brute Force Process
btn = new JButton("Test Password Strength");
btn.setBounds(10, 50, 260, 30);
panelObject.add(btn);
// Display Progress CheckBox
chkUpdateStatus = new JCheckBox("Display Progress");
chkUpdateStatus.setBounds(10, 85, 150, 30);
panelObject.add(chkUpdateStatus);
// Scroll Progress CheckBox
chkScrollUpdate = new JCheckBox("Scroll Progress");
chkScrollUpdate.setBounds(160, 85, 150, 30);
panelObject.add(chkScrollUpdate);
// Add filled JPanel to JFrame
panelObject.setBounds(this.getBounds());
getContentPane().add(panelObject);
// Add Button Action Listener
btn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (!workThreadIsRunning) {
// Clear the TextArea
txtStatus.setText(null);
new Thread(workThread).start();
}
if (btn.getText().equals("Cancel Test")) {
shutDownThread = true;
}
}
});
}
这意味着类构造函数(BruteForce())只包含:
public BruteForce() {
initializeComponents();
}
如果您不打算使用JFrame#pack()以便根据JFrame的所有内容自动调整其大小,使其达到或超过其首选大小,那么自行调整JFrame大小的setSize()方法对您帮助不大。您还需要使用setPreferredSize()在这种情况下,方法也是如此
创建表单时,您希望将JTextArea添加到JScrollPane,而不是JPanel。然后,它将是您添加到JPanel的JScrollPane
JTextArea的setBounds()不是必需的,因为它将填充整个JScrollPane容器。使用null布局时,您将使用需要提供setBounds()的JScrollPane
因为您使用的是Null布局,并且您的应用程序窗口
确实足够小,并且已经为所有组件设置了边界,还应该确保JFrame窗口不能调整大小(setresizeable(false);
)因为如果是这样的话,表单看起来会很可笑。我相信你已经被灌输了足够多的知识,知道为什么Null布局不一定是一个好的选择。但是如果这对你来说还不够,那么谷歌这个:。但是它在世界上确实有它的位置,特别是在使用多个布局时
旁注:
可以理解的是,当处理这样的事情时,在执行过程中看到过程的进展通常是很好的。可悲的现实是,速度在尝试这样做时受到了严重的阻碍
要通过在JTextArea上附加一行来有效地更新它,指示已处理的暴力尝试(迭代),您需要使用新线程来执行更新。这当然意味着处理(尝试)在单独的线程中执行,而不是在事件调度线程(EDT)中完成在所有处理完成之前,它不会更新JTextArea(这就是您在代码中所做的)。将处理代码放在自己的线程中,立即更新JTextArea确实是唯一可行的选择,但将更新写入JTextArea确实需要时间……事实上,这需要相当长的时间
例如,如果您运行下面提供的可运行代码(您的代码已修改),并提供密码2222222,在我的系统上,完成任务大约需要2147毫秒(约2秒)。如果您要注释掉textStatus.append(…)在循环中,您会发现只需约6毫秒(约0.006秒)完成任务。这在处理时间上是一个非常显著的差异,如果您正在执行类似于蛮力的操作,您希望获得每一点速度。如果您希望JTextArea自动滚动以显示视图端口中的每个更新,那么速度将受到更大的阻碍
通过使用我在下面的示例可运行代码中实现的复选框,进度显示应该是可选的,因为蛮力处理是在它自己的线程而不是EDT中完成的,所以对复选框的任何更改都会立即生效。该按钮还具有更多的切换效果,以便蛮力处理可以取消
以下是完整的代码:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class BruteForce extends javax.swing.JFrame {
JPanel panelObject;
JLabel lblPassword;
JTextField txtPassword;
JTextArea txtStatus;
JScrollPane scrollbar;
JButton btn;
JCheckBox chkUpdateStatus;
JCheckBox chkScrollUpdate;
Runnable workThread;
boolean workThreadIsRunning = false;
volatile boolean shutDownThread = false;
public BruteForce() {
initializeComponents();
workThread = new Runnable() {
@Override
public void run() {
long startTime = System.currentTimeMillis();
workThreadIsRunning = true;
int password = Integer.parseInt(txtPassword.getText());
btn.setText("Cancel Test");
int guess_password = 0;
while (guess_password != password & !shutDownThread) {
if (chkUpdateStatus.isSelected()) {
txtStatus.append("\n [+] Password Attempt: " + String.valueOf(guess_password + 1));
if (chkScrollUpdate.isSelected()) {
// Update The JTextArea to show immediate processing.
// (Slows down processing considerably)
txtStatus.setCaretPosition(txtStatus.getText().length() - 1);
}
}
guess_password++;
}
long duration = System.currentTimeMillis() - startTime;
if (guess_password == password) {
txtStatus.append("\n \n [-] Password Found: " + guess_password);
txtStatus.append("\n [-] It took " + duration + " milliseconds\n "
+ "(just over " + String.valueOf(duration / 1000) + " seconds) "
+ "to\n accomplish.");
txtStatus.setCaretPosition(txtStatus.getText().length() - 1);
}
workThreadIsRunning = false;
btn.setText("Test Password Strength");
shutDownThread = false;
}
};
}
private void initializeComponents() {
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
setTitle("Brute Force Tool");
setResizable(false);
setAlwaysOnTop(true);
// Size the Form
// Slightly different from original size since
// form has been made non-resizable. Makes the
// form more uniformed.
setPreferredSize(new Dimension(285, 325));
setSize(getPreferredSize());
// Center Form to screen. Should always be after sizing
setLocationRelativeTo(null);
panelObject = new JPanel();
panelObject.setLayout(null);
// Password Box Label
Font dialog = new Font("Dialog", Font.PLAIN, 14);
lblPassword = new JLabel("Password: ");
lblPassword.setBounds(10, 10, 100, 30);
lblPassword.setFont(dialog);
panelObject.add(lblPassword);
// Password Entry Text Field
txtPassword = new JTextField();
txtPassword.setBounds(80, 10, 190, 30);
panelObject.add(txtPassword);
// Text Area with Scroll Pane to display
// Brute Force process.
txtStatus = new JTextArea("Status: ");
scrollbar = new JScrollPane(txtStatus);
scrollbar.setBounds(10, 125, 260, 160);
panelObject.add(scrollbar);
// Button to start Brute Force Process
btn = new JButton("Test Password Strength");
btn.setBounds(10, 50, 260, 30);
panelObject.add(btn);
// Display Progress CheckBox
chkUpdateStatus = new JCheckBox("Display Progress");
chkUpdateStatus.setBounds(10, 85, 150, 30);
panelObject.add(chkUpdateStatus);
// Scroll Progress CheckBox
chkScrollUpdate = new JCheckBox("Scroll Progress");
chkScrollUpdate.setBounds(160, 85, 150, 30);
panelObject.add(chkScrollUpdate);
// Add filled JPanel to JFrame
panelObject.setBounds(this.getBounds());
getContentPane().add(panelObject);
// Add Button Action Listener
btn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (!workThreadIsRunning) {
// Clear the TextArea
txtStatus.setText(null);
new Thread(workThread).start();
}
if (btn.getText().equals("Cancel Test")) {
shutDownThread = true;
}
}
});
}
public static void main(String[] args) throws Exception {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
/* Create and display the form */
java.awt.EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
new BruteForce().setVisible(true);
}
});
}
}
请张贴您的code@RoyalSlayerYT第一件事不要使用
null
布局使用布局管理器。第二件事你不需要
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class BruteForce extends javax.swing.JFrame {
JPanel panelObject;
JLabel lblPassword;
JTextField txtPassword;
JTextArea txtStatus;
JScrollPane scrollbar;
JButton btn;
JCheckBox chkUpdateStatus;
JCheckBox chkScrollUpdate;
Runnable workThread;
boolean workThreadIsRunning = false;
volatile boolean shutDownThread = false;
public BruteForce() {
initializeComponents();
workThread = new Runnable() {
@Override
public void run() {
long startTime = System.currentTimeMillis();
workThreadIsRunning = true;
int password = Integer.parseInt(txtPassword.getText());
btn.setText("Cancel Test");
int guess_password = 0;
while (guess_password != password & !shutDownThread) {
if (chkUpdateStatus.isSelected()) {
txtStatus.append("\n [+] Password Attempt: " + String.valueOf(guess_password + 1));
if (chkScrollUpdate.isSelected()) {
// Update The JTextArea to show immediate processing.
// (Slows down processing considerably)
txtStatus.setCaretPosition(txtStatus.getText().length() - 1);
}
}
guess_password++;
}
long duration = System.currentTimeMillis() - startTime;
if (guess_password == password) {
txtStatus.append("\n \n [-] Password Found: " + guess_password);
txtStatus.append("\n [-] It took " + duration + " milliseconds\n "
+ "(just over " + String.valueOf(duration / 1000) + " seconds) "
+ "to\n accomplish.");
txtStatus.setCaretPosition(txtStatus.getText().length() - 1);
}
workThreadIsRunning = false;
btn.setText("Test Password Strength");
shutDownThread = false;
}
};
}
private void initializeComponents() {
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
setTitle("Brute Force Tool");
setResizable(false);
setAlwaysOnTop(true);
// Size the Form
// Slightly different from original size since
// form has been made non-resizable. Makes the
// form more uniformed.
setPreferredSize(new Dimension(285, 325));
setSize(getPreferredSize());
// Center Form to screen. Should always be after sizing
setLocationRelativeTo(null);
panelObject = new JPanel();
panelObject.setLayout(null);
// Password Box Label
Font dialog = new Font("Dialog", Font.PLAIN, 14);
lblPassword = new JLabel("Password: ");
lblPassword.setBounds(10, 10, 100, 30);
lblPassword.setFont(dialog);
panelObject.add(lblPassword);
// Password Entry Text Field
txtPassword = new JTextField();
txtPassword.setBounds(80, 10, 190, 30);
panelObject.add(txtPassword);
// Text Area with Scroll Pane to display
// Brute Force process.
txtStatus = new JTextArea("Status: ");
scrollbar = new JScrollPane(txtStatus);
scrollbar.setBounds(10, 125, 260, 160);
panelObject.add(scrollbar);
// Button to start Brute Force Process
btn = new JButton("Test Password Strength");
btn.setBounds(10, 50, 260, 30);
panelObject.add(btn);
// Display Progress CheckBox
chkUpdateStatus = new JCheckBox("Display Progress");
chkUpdateStatus.setBounds(10, 85, 150, 30);
panelObject.add(chkUpdateStatus);
// Scroll Progress CheckBox
chkScrollUpdate = new JCheckBox("Scroll Progress");
chkScrollUpdate.setBounds(160, 85, 150, 30);
panelObject.add(chkScrollUpdate);
// Add filled JPanel to JFrame
panelObject.setBounds(this.getBounds());
getContentPane().add(panelObject);
// Add Button Action Listener
btn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (!workThreadIsRunning) {
// Clear the TextArea
txtStatus.setText(null);
new Thread(workThread).start();
}
if (btn.getText().equals("Cancel Test")) {
shutDownThread = true;
}
}
});
}
public static void main(String[] args) throws Exception {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
/* Create and display the form */
java.awt.EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
new BruteForce().setVisible(true);
}
});
}
}