okay, so I recently made a java console application that brute forced your password so now I was working on a similar app but with a gui.
So I have all the code and its running but for some reason, a scroll bar I added to a textArea is not appearing and when I run the program iI get neither the scroll bar nor the text area.
Please tell me where I am going wrong and help me solve this issue.
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();
}
}
Please tell me where I am going wrong and correct my code.
Any help will be appreciated and thanks in advance.
First of all an important hint: Don't use null layout. Please learn all standard layout manager and use them to fill your UI. Also you can use some third-party layout manager like MigLayout or FormLayout (use Google to find them). These managers are often better then the standard.
Why is it better than null-layout? because Java-UI is cross-platform and some components can require different size on different OSs. The same can occur when the user uses some OS-features (like font scaling). Also layout manager defines the resize behavoir (what should happen when user changes the size of the window).
And here is the corrected version of your code (without layout manager change).
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.UIManager;
public class BruteForce {
static JFrame frameObject;
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: ");
// set bounds not required here. it's required for scrollbar
// 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);
// set the scroll bar bounds
scrollbar.setBounds(10, 95, 260, 160);
panelObject.add(scrollbar);
btn = new JButton("Test Password Strength");
btn.setBounds(10, 50, 260, 30);
panelObject.add(btn);
btn.addActionListener(new ActionListener() {
#Override
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");
BruteForce gui = new BruteForce();
frameObject.add(gui.panelObject); // don't forget to place your panel in the window
frameObject.setSize(300, 300);
frameObject.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frameObject.setLocationRelativeTo(null); // center location for window
frameObject.setVisible(true);
}
}
You do realize that you don't need an application to figure out that if you supply an integer password value (like 55673) and if you iterate through each value one at a time in a loop that it will take the password number of attempts (55673 iterations) to get to that password. We'll just chalk it up as an example. :/
In my opinion there are a number of issues with your particular project that needs some attention:
For a little easier coding, set the BruteForce Class so that it extends JFrame: public class BruteForce extends javax.swing.JFrame {. You won't need the static JFrame variable (frameObject) and it cleans things up somewhat.
Take out all that code related to the JFrame out of the main() method. Do your JFrame setup within a initialization method instead. In my opinion, I think your main() method would be better if you have:
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);
}
});
}
And your initialization method might look like this:
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;
}
}
});
}
Which then means that your class constructor (BruteForce()) simply contains:
public BruteForce() {
initializeComponents();
}
If you are not going to use JFrame#pack() so that JFrame is automatically sized according to all its contents at or above their preferred sizes then the setSize() method to size the JFrame on its own won't help you much. You will also need to use the setPreferredSize() method as well in this case.
When creating your form, you want to add JTextArea into the JScrollPane, not the JPanel. It will then be the JScrollPane you add into the JPanel.
The setBounds() for JTextArea is not required since it will be filling the entire JScrollPane container. With the null layout you are using it will be the JScrollPane which will need the setBounds() supplied.
Since you are using the Null layout and your application window is
indeed small enough, and you've set boundries for all the components, you should also ensure that the JFrame window can not be resized (setResizable(false);) since the form would look ridiculous if it was. I'm sure you've been preached to enough to know why Null Layout is not necessarily a good choice. But if that isn't enough for you then Google this: Why is null layout in Swing frowned upon?. It does however have its place in the world especially when utilizing multiple layouts.
On a side note:
Understandably, when processing something like this it is usually nice to see the progress of that process while it is being carried out. The sad reality is that speed is seriously hampered when trying to do so.
To effectively update the JTextArea by appending a line to it indicating the brute force attempt (iteration) processed you need to use a new thread to carry out that updating. This of course means that the processing (attempts) are carried out in a separate Thread and not done within the Event Dispatch Thread (EDT) which will not update the JTextArea until all the processing is complete (which is what you are doing in your code). By placing the processing code within its own thread that updates the JTextArea immediatly is really the only viable option but it does takes time to write that update to the JTextArea...considerable time as a matter of fact.
As an example if you run the supplied runnable code (your code modified) below and supply a password of 222222, on my system it will take about 2147 milliseconds (around 2 seconds) to complete the task. If you were to comment out the textStatus.append(...) within the loop you would find that it only takes about 6 milliseconds (around 0.006 seconds) to complete the task. This is a very significant difference in processing time and if you're doing something like Brute Force you want every scrap of speed you can get. If you want the JTextArea to automatically scroll so as to display each update within the view port then speed is hampered much much more.
Progress display should be made optional with the use of Check Boxes which I did implement in the sample runnable code below and because the brute force processing is done within its own thread rather than the EDT, any changes to the Check Boxes takes immediate affect. The button also has a more toggle effect so that brute force processing can be canceled.
Here's the full code:
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);
}
});
}
}
Related
I am new to Java and have just tried out Java's swing, I tried making a log in form that would print the content of a JTextField to the console, but the console doesn't show anything when I tried it.
Here's my code:
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JTextField;
import javax.swing.JButton;
public class JavaTextField {
private JFrame frame;
private JTextField text1;
private JTextField text2;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
JavaTextField window = new JavaTextField();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the application.
*/
public JavaTextField() {
initialize();
}
/**
* Initialize the contents of the frame.
*/
private void initialize() {
frame = new JFrame();
frame.setBounds(100, 100, 450, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(null);
text1 = new JTextField();
text1.setBounds(114, 38, 122, 40);
frame.getContentPane().add(text1);
text1.setColumns(10);
String majorText = text1.getText();
text2 = new JTextField();
text2.setBounds(114, 117, 86, 20);
frame.getContentPane().add(text2);
text2.setColumns(10);
String minorText = text2.getText();
JButton btnButton = new JButton("Button");
btnButton.setBounds(132, 192, 159, 40);
frame.getContentPane().add(btnButton);
btnButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.out.println(majorText);
System.out.println(minorText);
}
}
);
}
}
I'm glad if anyone could point me in the right direction, because I haven't seen the solution to this problem on the internet yet.
The issue here is, that you retrieve the content from the JTextFields at the wrong time. Currently you call getText() right when the components are being initialized. Of course, the content returned from getText() will be an empty String.
So to fix the issue in your logic, you should actually retrieve the majorText and minorText from the JTextFields only once your JButton has been pressed. Because at that point in time, when your button is pressed, the content of your text fields should be correct. To do that, move the retrieval of the text to the ActionListener.
The updated ActionListener should look as follows:
btnButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
String majorText = text1.getText();
String minorText = text2.getText();
System.out.println(majorText);
System.out.println(minorText);
}
}
or simply:
btnButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.out.println(text1.getText());
System.out.println(text2.getText());
}
}
Sidenote (as also mentioned by the other answer):
Using null layout is highly discouraged, as it is a frequent source for unnecessary errors. Have a look at the different LayoutManagers available and how and when to use them.
There are some improvements to do in your code:
Avoid the use of null-layout and setBounds(...), see why should you avoid it and a graphic example along with a suggestion to fix it by using layout managers
Your majorText is getting the text BEFORE you click on the button, and by that time it's empty and never update it, you need to get the text on button click, so move this line:
String majorText = text1.getText();
Inside your actionListener, same thing for minorText
And if you tagged your question with Java 8, then you could rewrite your listener using Java 8 lambdas
btnButton.addActionListener(e -> {
String majorText = text1.getText();
String minorText = text1.getText();
System.out.println(majorText);
System.out.println(minorText);
}
Im creating a programme using java. I want the user to enter some text, then push the button so the text entered shows in the label. However, I have 2 problems. First, the text are isn´t displaying when I execute the app. Second, I don´t know how to allow the user to type in the area. Im new in java so that´s why Im asking. Here is the code. Thank you.
import javax.swing.*;
import java.awt.event.*;
class Boton extends JFrame implements ActionListener {
JButton boton;
JTextArea textArea = new JTextArea();
JLabel etiqueta = new JLabel();
public Boton() {
setLayout(null);
boton = new JButton("Escribir");
boton.setBounds(100, 150, 100, 30);
boton.addActionListener(this);
add(boton);
}
#Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == boton) {
try {
String texto = textArea.getText();
etiqueta.setText(texto);
Thread.sleep(3000);
System.exit(0);
} catch (Exception excep) {
System.exit(0);
}
}
}
}
public class Main{
public static void main(String[] ar) {
Boton boton1 =new Boton();
boton1.setBounds(0,0,450,350);
boton1.setVisible(true);
boton1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
Problems:
You never add the JTextArea into your GUI, and if it doesn't show, a user cannot directly interact with it.
You are calling Thread.sleep on the Swing event thread, and this will put the entire application to sleep, meaning the text that you added will not show.
Other issues include use of null layouts and setBounds -- avoid doing this.
Solutions:
Set the JTextArea's column and row properties so that it sizes well.
Since your JTextArea's text is going into a JLabel, a component that only allows a single line of text, I wonder if you should be using a JTextArea at all. Perhaps a JTextField would work better since it allows user input but only one line of text.
Add the JTextArea to a JScrollPane (its viewport actually) and add that to your GUI. Then the user can interact directly with it. This is most easily done by passing the JTextArea into a JScrollPane's constructor.
Get rid of the Thread.sleep and instead, if you want to use a delay, use a Swing Timer. check out the tutorial here
For example:
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.Window;
import java.awt.event.KeyEvent;
import javax.swing.*;
public class Main2 {
public static void main(String[] args) {
// create GUI in a thread-safe manner
SwingUtilities.invokeLater(() -> createAndShowGui());
}
private static void createAndShowGui() {
BotonExample mainPanel = new BotonExample();
JFrame frame = new JFrame("GUI");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
}
class BotonExample extends JPanel {
private JLabel etiqueta = new JLabel(" ");
private JButton boton = new JButton("Escribir");
// jtext area rows and column properties
private int rows = 5;
private int columns = 30;
private JTextArea textArea = new JTextArea(rows, columns);
public BotonExample() {
// alt-e will activate button
boton.setMnemonic(KeyEvent.VK_E);
boton.addActionListener(e -> {
boton.setEnabled(false); // prevent button from re-activating
String text = textArea.getText();
etiqueta.setText(text);
// delay for timer
int delay = 3000;
Timer timer = new Timer(delay, e2 -> {
// get current window and dispose ofit
Window window = SwingUtilities.getWindowAncestor(boton);
window.dispose();
});
timer.setRepeats(false);
timer.start(); // start timer
});
// create JPanels to add to GUI
JPanel topPanel = new JPanel(new FlowLayout(FlowLayout.LEADING, 5, 5));
topPanel.add(new JLabel("Etiqueta:"));
topPanel.add(etiqueta);
JPanel bottomPanel = new JPanel();
bottomPanel.add(boton);
JScrollPane scrollPane = new JScrollPane(textArea);
// use layout manager and add components
setLayout(new BorderLayout());
add(topPanel, BorderLayout.PAGE_START);
add(scrollPane, BorderLayout.CENTER);
add(bottomPanel, BorderLayout.PAGE_END);
}
}
textarea.setText("Text"); // this will insert text into the text area
textarea.setVisable(true); // this will display the text area so you can type in it
textarea.setSize(500,500); // set size of the textarea so it actually shows
The user should be able to type in the TA when it is displayed and just do a getText to pull the text
The commented codes are the problem. When I am using them, panels are added successfully, but I don't need these commented code anymore but same code is not working after I remove or comment those blocks.
Those codes that I have commented need to be removed. Without those commented codes, program runs but does not add panels. I use IntelliJ for my Java Project.
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import java.awt.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
public class Test extends JFrame{
JPanel panel;
JButton send;
JTextField text;
JPanel chatArea;
boolean typing;
Test(){
setSize(365,515);
setLocation(50,100);
setLayout(null);
panel = new JPanel();
panel.setLayout(null);
panel.setBounds(0,0,350,60);
panel.setBackground(new Color(90000000));add(panel);
JLabel name = new JLabel("IRONMAN");
name.setFont(new Font("SAN_SERIF", Font.PLAIN,14));
name.setForeground(Color.white);
name.setBounds(110,35,120,20);panel.add(name);
text = new JTextField();
text.setBounds(15,430,260,40);
text.setFont(new Font("SAN_SERIF",Font.PLAIN,14));
text.setForeground(Color.BLUE);
// Timer timer = new Timer(1, event -> {
// if (!typing){
// name.setText("IRONMAN");
// }
// });
// timer.setInitialDelay(2000);
// text.addKeyListener(new KeyAdapter() {
// #Override
// public void keyPressed(KeyEvent e) {
// name.setText("IRONMAN typing...");
// timer.stop();
// typing = true;
// }
// #Override
// public void keyReleased(KeyEvent e) {
// typing = false;
// if (!timer.isRunning()){
// timer.start();
// }
// }
// });
add(text);
chatArea = new JPanel();
chatArea.setBounds(5,65,340,350);
add(chatArea);
send = new JButton("Send");
send.setBounds(280,430,65,30);
send.setBackground(new Color(200,120,255));
send.setForeground(new Color(7,95,75));
send.addActionListener(e -> {
String message = "STARK: "+text.getText();
JPanel p2 = formatLabel(message);
chatArea.add(p2);
text.setText("");
});
add(send);
}
private JPanel formatLabel(String message) {
JPanel p3 = new JPanel();
JLabel label1 = new JLabel("<html><p style = \"width : 150px\">" + message + "</p></html>");
label1.setBackground(new Color(200,120,255));
label1.setForeground(new Color(7,95,75));
label1.setFont(new Font("SAN_SERIF",Font.PLAIN,18));
label1.setOpaque(true);
label1.setBorder(new EmptyBorder(15,15,15,70));
p3.add(label1);
return p3;
}
public static void main(String[] args) {
Test t = new Test();
t.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
t.setVisible(true);
}
}
First off all some general comments:
label1.setBorder(new EmptyBorder(15,15,15,70));
Don't be afraid to use whitespace. For example
label1.setBorder(new EmptyBorder(15, 15, 15, 70));
It is easier for our eyes to see text with whitespace.
setLayout(null);
Don't use a null layout. Swing was designed to be used with layout managers. You can easily use the default BorderLayout of the JFrame. Add:
the top panel to BorderLayout.PAGE_START
the chat panel to BorderLayout.PAGE_CENTER
the bottom panel to BorderLayout.PAGE_END
after I remove or comment those blocks.
That code is not the solution or the problem.
The problem is that a component has a size of (0, 0) so there is nothing to paint.
In your existing code try resizing the frame by making it wider. The panel will appear. This is because the resizing will cause the layout manager to be invoked which will give the panel a size so it can be painted.
In your code you need to use:
chatArea.add(p2);
chatArea.revalidate();
The revalidate() will automatically invoke the layout manager.
I work with NetBeans 7.2.
I have a JSlider slider_random in my JPanel1, entered the value 100, minimum 0, maximum 1000. I set a toolTipText for slider_random via properties (custom code):
"<html>Range (0-" + String.valueOf(slider_random.getMaximum()) + ")<br>Current: " + String.valueOf(slider_random.getValue())
Also placed a JTextField text_current and set the text to 100, This displays the value of slider_random when I change it.
I set stateChanged event to slider_random:
private void slider_randomStateChanged(javax.swing.event.ChangeEvent evt) {
slider_random.setToolTipText("<html>Range (0-" + String.valueOf(slider_random.getMaximum()) + ")<br>Current: " + String.valueOf(slider_random.getValue()));
jTextField1.setText(String.valueOf(slider_random.getValue()));
}
My problem is when I start the program and point to the slider it shows:
Range (0-1000)
Current: 50
Then move the slider a little, and move back to the original position (meanwhile I can see changes in text_current) all data become correct, and the tooltip says:
Range (0-1000)
Current: 100
What can cause my problem?
Here's the screenshot, after I lauched it.
I was able to repro your issue.
The problem is that jSlider's default value is 50. You modified the value to 100, but this was not reflected in jSlider's setToolTip() method where you access jSlider's value (thru the custom code). It would show the old value of 50.
To correct this, one solution is to create a mouse hover event on the slider, so that when you run your application and hover the mouse pointer over the slider, jToolTip method picks the latest value and shows you the same. It worked for me, so i'm sure it'll work for you.
If i can think of a better solution, i'll post the same.
Maybe the listener is added after the value of the slider was already set. You may need to change the order. Or, just to fix the initialization issue you may need to set the tooltip explicitly once you initialize the slider.
As an alternative you can subclass JSlider and override getToolTipText, for example:
JSlider slider = new JSlider() {
public String getToolTipText(MouseEvent e) {
return "<html>Range (0-" + String.valueOf(getMaximum()) + ")<br>Current: " + String.valueOf(getValue());
}
};
Here is a short demo:
import java.awt.event.MouseEvent;
import javax.swing.BorderFactory;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JSlider;
public class TestSlider {
public static void main(String[] args) {
JFrame frame = new JFrame("TestSlider");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JSlider slider = new JSlider() {
public String getToolTipText(MouseEvent e) {
return "<html>Range (0-" + String.valueOf(getMaximum())
+ ")<br>Current: " + String.valueOf(getValue());
}
};
slider.setToolTipText("");
frame.add(slider);
((JComponent) frame.getContentPane()).setBorder(BorderFactory
.createEmptyBorder(10, 10, 10, 10));
frame.setLocationByPlatform(true);
frame.pack();
frame.setVisible(true);
}
}
i think the best way to do this action,is to make a label near to your slider then put an variable like an integer instead of "y" or put the get value instead of "y",& the event which you need for this is Item state change ,so when you move your slider the label will move with the slider & is going to show the value ;)
public class Slidebar extends JFrame {
private JPanel contentPane;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
Slidebar frame = new Slidebar();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the frame.
*/
public Slidebar() {
setResizable(false);
setTitle("SlideBar With Text Move");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 317, 300);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
contentPane.setLayout(null);
final JSlider slider = new JSlider();
slider.setPaintLabels(true);
slider.setOrientation(SwingConstants.VERTICAL);
slider.setValue(0);
slider.setBounds(131, 60, 53, 136);
contentPane.add(slider);
final JLabel lblNewLabel = new JLabel("");
int y = 165;
lblNewLabel.setBounds(111, 173, 41, 30);
contentPane.add(lblNewLabel);
slider.addChangeListener(new ChangeListener() {
public void stateChanged(ChangeEvent arg0) {
int y=165;
lblNewLabel.setBounds(111, y-(slider.getValue())-5, 41, 30);
lblNewLabel.setText(slider.getValue()+"");
}
});
}
}
I'm trying to create a board for a game, i first made a frame then if the user //enters the rows and columns as numbers and pushes the start button, it should remove all //whats on frame and add a panel with a grid layout having buttons everywhere
Here is the code ( Problem is the frame gets cleared and nothing appears)
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class Frame extends JFrame implements ActionListener{
private static final long serialVersionUID = 1L;
JButton newButton;
JButton Start;
JTextArea row;
JTextArea col;
JLabel background;
JLabel rows;
JLabel columns;
JLabel Error;
JPanel myPanel;
JCheckBox box;
public Frame()
{
//adding frame
setTitle("DVONN Game");
setSize(1000, 700);
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(null);
//making start button
Start = new JButton(new ImageIcon("Start"));
Start.setBounds(500, 30, 300, 300);
Start.setOpaque(true);
Start.addActionListener(this);
//make background
background = new JLabel();
background.setBounds(0, -300, 2000, 1500);
background.setIcon(Color.BLUE));
rows = new JLabel("Enter the rows");
columns = new JLabel("Enter the columns");
rows.setForeground(Color.WHITE);
columns.setForeground(Color.WHITE);
rows.setBounds(10,10,100,30);
columns.setBounds(10,45,105,30);
row = new JTextArea();
col = new JTextArea();
row.setBounds(120,10,100,30);
col.setBounds(120,45,100,30);
Error = new JLabel("Enter numbers plz!");
Error.setBounds(10, 100, 400, 30);
Error.setForeground(Color.RED);
Error.setVisible(true);
box = new JCheckBox("Enable Random Filling");
box.setBounds(10, 200, 150, 20);
box.setVisible(true);
myPanel = new JPanel();
myPanel.setBounds(30, 30, 700, 500);
myPanel.setVisible(true);
newButton = new JButton();
newButton.setOpaque(true);
getContentPane().add(box);
getContentPane().add(rows);
getContentPane().add(columns);
getContentPane().add(row);
getContentPane().add(col);
getContentPane().add(Start);
getContentPane().add(background);
this.validate();
this.repaint();
}
public static void main(String[]args)
{
new Frame();
}
//adding actions for start button
public void actionPerformed(ActionEvent e) {
boolean flag = true;
String r1 = row.getText();
String c1 = col.getText();
int x = 0,y = 0;
try{
x = Integer.parseInt(r1);
y = Integer.parseInt(c1);
} catch(NumberFormatException l) {
flag = false;
}
int size = x * y;
if (flag == true) {
this.getContentPane().removeAll();
this.validate();
this.repaint();
myPanel.setLayout(new GridLayout(x, y));
while(size != 0)
{
myPanel.add(newButton);
size --;
}
this.getContentPane().add(myPanel);
} else {
this.getContentPane().add(Error);
}
}
}
There are several issues with this code
Is it really needed to post that much code. A simple UI with one button to press, and then another component which should appear would be sufficient for an SSCCE
The use of null layout's. Please learn to use LayoutManagers
Each Swing component can only be contained once in the hierarchy. So this loop is useless since you add the same component over and over again (not to mention that a negative size would result in an endless loop)
while(size != 0){
myPanel.add(newButton);
size --;
}
Have you tried debugging to see whether size is actually >0. Since you silently ignore ParseExceptions you might end up with a size of 0 which will clean the content pane and add nothing
Then do as goldilocks suggests and call validate after adding the components. See the javadoc of the Container#add method
This method changes layout-related information, and therefore, invalidates the component hierarchy. If the container has already been displayed, the hierarchy must be validated thereafter in order to display the added component.
Call validate() and repaint() after the new elements have been added instead of after the old ones have been removed.
You don't need to be calling setVisible() on individual components, call it after pack() on the Frame itself, and you shouldn't use validate() and repaint() in the constructor. Ie, replace those with:
pack();
setVisible(true);
or you can do that on the object after the constructor is called.
Try to replace
public static void main(String[]args)
{
new Frame();
}
by
public static void main(String[]args)
{
new Frame().setVisible(true);
}
Remove the call to this.setVisible in the constructor and make this your main method.
public static void main(String[] args) {
final Frame fr = new Frame();
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
fr.setVisible(true);
}
});
}
This will make sure that the frame elements will be in place before it becomes visible.