GUI and application logic of WindowBuilder interaction java? - java

i have a MainWindow class which has main method,its constructor and initialize() method. The initialize() method has frame, Jbutton and a final Jtextarea. The actionPerformed() is in the another class Data which handles ActionListener. I want to display some text after the button is pressed in the Jtextfield which is inside only private variable frame of the MainWindow class.I haven't mentioned the Application logic, help me interact with it and GUI.. thank you !!!!!
The MainWindow class:
public class MainWindow {
private JFrame frame;
public Data data;
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
MainWindow window = new MainWindow();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
public MainWindow() {
this.data = new Data();
initialize();
}
private void initialize(){
frame = new JFrame();
frame.setBounds(100, 100, 396, 469);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(null);
final JTextArea textarea = new JTextArea();
textarea.setFont(new Font("Dialog", Font.PLAIN, 75));
textarea.setTabSize(15);
textarea.setBounds(12, 28, 370, 85);
frame.getContentPane().add(textarea);
JButton button7 = new JButton("7");
button7.addActionListener(this.data); // Data data class has the actionperformed() method
button7.setActionCommand("7");
button7.setBounds(12, 125, 65, 73);
frame.getContentPane().add(button7);
}
}
Then the class Data is:
public class Data implements ActionListener {
public String s;
public Data(){
//constructor
}
public void actionPerformed(ActionEvent e) {
// this will set string s with some string
// that has to be returned to be displayed
// in the Jtextarea of the frame in MainWindow
}
public string returnString(){
return s;
}
i just want to set the JtextArea of the frame variable in MainWindow class..please help

If I understand correctly, you can simply pass the reference of the TextArea to your ActionListener via getter or constructor. Here I just used getter
public class Data implements ActionListener {
public JTextArea textArea;
public Data() {
//constructor
}
// here I used setter
public void setTextArea( JTextArea textArea ) {
this.textArea = textArea;
}
public void actionPerformed(ActionEvent e) {
// this will work, if you click the button 7
textArea.setText("Any modification you want");
}
}
And add this code in your initialize() method after textarea initialization
this.data.setTextArea(textarea);
Hope it helps.
UPDATE
public class MainWindow {
private JFrame frame;
public Data data;
final JTextArea textarea;
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
MainWindow window = new MainWindow();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
public class Data implements ActionListener {
public String s;
public MainWindow mainWindow;
public Data( MainWindow mainWindow ) {
this.mainWindow = mainWindow;
//constructor
}
public void actionPerformed(ActionEvent e) {
s = "test";
// this will set string s with some string
// that has to be returned to be displayed
// in the Jtextarea of the frame in MainWindow
mainWindow.updateTextArea(s);
}
public String returnString() {
return s;
}
}
That is just a simple implementation.

Related

Access JLabel from another class

So, I'm trying to access the (only) label "lblNewLabel" in class "TesteRotulo" from class "Controle".
public class TesteRotulo {
private JFrame frame;
private JLabel lblNewLabel;
// getter for the label to be accessed by class Controle
public JLabel getLblNewLabel() {
return lblNewLabel;
}
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
TesteRotulo window = new TesteRotulo();
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the application.
*/
public TesteRotulo() {
initialize();
// instantiate new object Controle having this instance of Testerotulo as parameter
Controle c = new Controle(TesteRotulo.this);
c.setRotulo();
}
/**
* Initialize the contents of the frame.
*/
private void initialize() {
frame = new JFrame();
frame.setBounds(100, 100, 450, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JLabel lblNewLabel = new JLabel();
frame.getContentPane().add(lblNewLabel, BorderLayout.CENTER);
frame.setVisible(true);
}
}
The class Controle that should access the label in TesteRotulo
public class Controle {
private TesteRotulo jM;
private JFrame janela;
private JLabel rotulo;
public Controle(TesteRotulo jM) {
this.jM = jM;
}
public void setRotulo() {
this.rotulo = jM.getLblNewLabel();
rotulo.setText("teste");
}
}
So I think having the reference for the (only) instance of TesteRotulo I should be able to access the label.
But to no avail. Always get a null pointer exception.
What is wrong?
Thanks in advance...
Your label in initialize is a local variable. JLabel lblNewLabel = new JLabel();
You should write this.lblNewLabel = new JLabel();

passing values from JPanel class to JFrame class

I have a JFrame which uses JPanel initialized from the JPanel.
This is the JFrame class : LoginPage
public class LoginPage extends JFrame
{
private JPanel contentPane;
static int cnf;
static String data;
private static LoginPage frame;
/**
* Launch the application.
*/
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
try
{
frame = new LoginPage();
frame.setVisible(true);
}
catch (Exception e)
{
e.printStackTrace();
}
}
});
//cnf = chk;
if( cnf == 1)
{
frame.dispose();
JFrame m = new MainPage();
m.setVisible(true);
}
}
/**
* Create the frame.
*/
public LoginPage()
{
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 450, 300);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
contentPane.setLayout(null);
JPanel m = new MainLogin();
m.setBounds(0, 0, 448, 271);
contentPane.add(m);
}
}
And, this is the JPanel class : MainLogin
public class MainLogin extends JPanel
{
private JTextField uname;
private JPasswordField pass;
public static int chk;
public MainLogin()
{
setLayout(null);
uname = new JTextField();
uname.setBounds(236, 22, 167, 25);
add(uname);
uname.setColumns(10);
pass = new JPasswordField();
pass.setBounds(236, 53, 167, 25);
add(pass);
JButton login = new JButton("Login");
login.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
String u = uname.getText();
char[] tp = pass.getPassword();
String p = new String(tp);
chk = authentication.verify(u, p);
System.out.println(chk);
}
});
login.setBounds(235, 90, 117, 25);
add(login);
}
}
As in the MainLogin Panel, there is a class authentication who has a method verify(), which returns an integer, and this integer is stored in chk.
Since, this chk resides in MainLogin JPanel class, I want to pass it to the LoginPage JFrame class.
Is there any way to do this other than using a File?
Open the main page from LoginPage instance not from the main method.
Add a login() method to the LoginPage
public class LoginPage extends JFrame {
//other parts
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
try
{
frame = new LoginPage();
frame.setVisible(true);
}
catch (Exception e)
{
e.printStackTrace();
}
}
});
}
public LoginPage() {
//...
JPanel m = new MainLogin(this);
//...
}
public void login(int chk) {
JFrame m = new MainPage();
m.setVisible(true);
this.dispose();
}
}
And pass login frame to the panel as a parameter
public class MainLogin extends JPanel
{
private int chk;//no need to be static
public MainLogin(final LoginFrame loginFrame)
{
setLayout(null);//null layout is bad
//...
login.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
//...
chk = authentication.verify(u, p);
loginFrame.login(chk);
}
});
//...
}
}
Not only does this question get asked quite a bit, it also has a number of possible solutions, including using a modal dialog or Observer Pattern depending on your needs
See How to Make Dialogs for more details
You might also like to take a look at
Open JFrame, only after successfull login verification with database. Using Eclipse?
Java and GUI - Where do ActionListeners belong according to MVC pattern?
for more discussion on the subject
The basic answer here is, you want to separate the areas of responsibility.
You need to:
Gather the user credentials
Validate those credentials
Take a appropriate action based on the success of that check
These are three distinct actions, all which should be separated, it's not the responsibility of the login panel to validate the credentials, that's someone else's responsibility, equally, it's not the validators responsibility to decide what should be done when the validation fails or succeeds, that's someone else's responsibility

Java: CardLayout switching between cards

I've got class 'Frame' which extends JFrame and separetad JPanels: MainMenu and SinglePanel
I am using CardLayout, but I've got problem when switching back to panels using buttonSingle and powrot buttons. So my question is how can I change/swap between cards using these buttons?
My Frame class:
public class Frame extends JFrame{
CardLayout cl = new CardLayout();
final MainMenu menuPanel = new MainMenu();
final SinglePanel singlePanel = new SinglePanel();
public Frame(){
setLayout(cl);
add(menuPanel,"menu");
add(singlePanel,"single");
setSize(200, 200);
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
setVisible(true);
setEnabled(true);
swapView("menu");
}
public void swapView(String view){
cl.show(getContentPane(),view);
}
}
my MainMenu class:
public class MainMenu extends JPanel{
public MainMenu(){
setLayout(new BoxLayout(this , BoxLayout.Y_AXIS));
add(Box.createVerticalGlue());
JButton buttonSingle = new JButton("Single");
buttonSingle.setAlignmentX(Component.CENTER_ALIGNMENT);
buttonSingle.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent e) {
}
});
add(buttonSingle);
add(Box.createVerticalGlue());
JButton buttonMulti = new JButton("Multiplayer");
buttonMulti.setAlignmentX(Component.CENTER_ALIGNMENT);
buttonMulti.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent e) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
});
add(buttonMulti);
add(Box.createVerticalGlue());
JButton buttonExit = new JButton("Wyjście");
buttonExit.setAlignmentX(Component.CENTER_ALIGNMENT);
buttonExit.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent e) {
System.exit(0);
}});
add(buttonExit);
add(Box.createVerticalGlue());
}
}
my SinglePanel class
public class SinglePanel extends JPanel{
SinglePanel(){
setLayout(new FlowLayout());
JButton powrot = new JButton("Wróć do menu");
powrot.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent e) {
}
});
add(powrot);
}
}
Main class:
public class Main {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here
/*MainMenu mM = new MainMenu();*/
Frame f = new Frame();
}
}
You need a reference to the CardLayout of the JFrame inside your panel classes. What you can do is pass the Frame to the JPanel classes as reference, then you can use the CardLayout of the Frame in those classes to show or next etc. Something like
public class MainMenu {
private CardLayout layout;
private Frame frame;
public MainMenu(final Frame frame) {
this.frame = frame;
this.layout = (CardLayout)frame.getLayout();
JButton buttonSingle = new JButton("Single");
buttonSingle.setAlignmentX(Component.CENTER_ALIGNMENT);
buttonSingle.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent e) {
layout.show(frame, "single");
}
});
}
}
When you create the MainPanel, you need to pass Frame.this to it, referencing the current Frame
MainMenu menuPanel = new MainMenu(Frame.this);
EDIT
I just noticed your swapView method. So instead of use the CardLayout directly in the panel class, you can actually just call swapView in the actionPerformed
frame.swapView("single");
Or better yet, as to not expose the Frame class, you can have the Frame class implement an interface say SwapInterface that has a method swapView you need to override. And pass the SwapInterface to the panel classes. Something like
public interface SwapInterface {
public void swapView(String view);
}
public Frame extends JFrame implements SwapInterface {
MainMenu mainPanel = new MainMenu(Frame.this);
....
#Override
public void swapView(String view) {
cl.show(getContentPane(), view);
}
}
public class MainMenu extends JPanel {
private SwapInterface swap;
public MainMenu(SwapInterface swap) {
this.swap = swap;
...
public void actionPerfomed(ActionEvent e) {
swap.swapView("single");
}
}
}
Side Note
As HovercraftFullOfEels pointed out in his comment, you should make use of String contants for the String card values so there's no mistakes. Something like
private static final String SINGLE_CARD = "single";
Then in places where you use "single", use SINGLE_CARD instead

Sending Jframe Jtextfield to another class

I have a JFrame that has a textfield and a button. It should become visible at the start of program and when I click on the button, It should become invisible and send the text of textfield to another class. but It send nothing and when I click on the button the IDE goes to the debug mode.
public class JframeFoo extends JFrame {
private String username = new String();
public JframeFoo() {
// --------------------------------------------------------------
// Making Frame for login
final JTextField usernameFiled = new JTextField();
this.add(usernameFiled);
JButton signinButton = new JButton();
// ------------------------------------------------------------
signinButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
username = usernameFiled.getText();
setVisible(false);
Main.mainpage.setVisible(true);
}
});
// --------------------------------------------------------------------------
}
public String getuserName() {
return this.username;
}
}
my another class calls Jframe:
System.out.println(JframeFoo.getusername);
Ignoring for a moment that having multiple JFrames jumping out at the user is not a great user interface design, for one object to communicate with another object, it must have a valid reference to the other object. (sorry interrupted by daughter).
So for one JFrame class to get information from the other, it must have a reference to the first object that gets the text, and I don't see you passing that reference, such as in a constructor or setter method.
So for instance if an object of Class1 has information that an object of Class2 needs, then one way to pass it is to give Class2 a reference to the valid instance of Class1, and then have Class2 get the information from the Class1 instance. e.g.,
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import javax.swing.*;
public class ClassMain {
private static void createAndShowGui() {
ClassMain mainPanel = new ClassMain();
JFrame frame = new Class1();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
class Class1 extends JFrame {
private JTextField textfield = new JTextField(10);
public Class1() {
JPanel contentPane = (JPanel) getContentPane();
contentPane.setLayout(new FlowLayout());
add(textfield);
add(new JButton(new AbstractAction("Open Window") {
#Override
public void actionPerformed(ActionEvent arg0) {
Class2 class2 = new Class2(Class1.this);
Class1.this.setVisible(false);
class2.pack();
class2.setVisible(true);
class2.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}));
}
public String getTextfieldText() {
return textfield.getText();
}
}
class Class2 extends JFrame {
private Class1 class1;
private JLabel label = new JLabel("");
public Class2(Class1 class1) {
this.class1 = class1;
label.setText(class1.getTextfieldText());
add(label);
}
}

Deselect default selection on JTextfield

When using JTextFields i like to set a default text.
Then i run the program and this default text will automatically be selected (at least when you have only one field). In other words, if I type a letter right away, the default text will be deleted and replaced by the new one.
My question is how I can change the default settings in a way that allows me to type a letter without deleting the default text? I would like the letter to just be added at the end of the default text.
Here's my code:
public class ButtonsNText extends JPanel implements ActionListener, KeyListener {
private JTextField TextLine;
private JToggleButton UpperCaseButton;
private JToggleButton LowerCaseButton;
private JCheckBox ContinuousButton;
private ButtonGroup myButtonGroup;
public ButtonsNText(){
TextLine = new JTextField(10);
add(TextLine); TextLine.setName("TextLine");
TextLine.setText("default text");
TextLine.setCaretPosition(TextLine.getText().length());
TextLine.addKeyListener(this);
myButtonGroup = new ButtonGroup();
UpperCaseButton = new JToggleButton("Upper case");
add(UpperCaseButton);UpperCaseButton.setName("UpperCaseButton");
LowerCaseButton = new JToggleButton("Lower case");
add(LowerCaseButton); LowerCaseButton.setName("LowerCaseButton");
ContinuousButton = new JCheckBox("Continuous?");
add(ContinuousButton); ContinuousButton.setName("ContinuousButton");
myButtonGroup.add(UpperCaseButton); myButtonGroup.add(LowerCaseButton);
UpperCaseButton.addActionListener(this);
LowerCaseButton.addActionListener(this);
ContinuousButton.addActionListener(this);
}
public static void main(String[] args) {
JFrame frame = new JFrame("Hello world example");
frame.add(new ButtonsNText());
frame.pack();
frame.setVisible(true);
}
#Override
public void actionPerformed(ActionEvent e) {
if(e.getSource() == UpperCaseButton){
TextLine.setText(TextLine.getText().toUpperCase());
}
else if(e.getSource() == LowerCaseButton){
TextLine.setText(TextLine.getText().toLowerCase());
}
}
#Override
public void keyReleased(KeyEvent k) {
if(ContinuousButton.isSelected()){
if(UpperCaseButton.isSelected()){
int pos = TextLine.getCaretPosition();
TextLine.setText(TextLine.getText().toUpperCase());
TextLine.setCaretPosition(pos);
}
else if(LowerCaseButton.isSelected()){
int pos = TextLine.getCaretPosition();
TextLine.setText(TextLine.getText().toLowerCase());
TextLine.setCaretPosition(pos);
}
}
int key = k.getKeyCode();
if(key == KeyEvent.VK_ENTER){
if(UpperCaseButton.isSelected()){
TextLine.setText(TextLine.getText().toUpperCase());
}
else if(LowerCaseButton.isSelected()){
TextLine.setText(TextLine.getText().toLowerCase());
}
}
}
}
I have tried things like isFocusable(), setFocusable(), setCaterPosition() and other similar methods, but here I think I need a different approach.
Just add one FocusListener for focus Gained, that will do for you along with tfield2.setCaretPosition(tfield2.getDocument().getLength());
Here see the code for your help :
import java.awt.event.*;
import javax.swing.*;
public class TextFieldExample extends JFrame
{
public TextFieldExample()
{
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
JPanel contentPane = new JPanel();
JTextField tfield = new JTextField(10);
final JTextField tfield2 = new JTextField(10);
tfield2.setText("default text");
tfield2.addFocusListener(new FocusListener()
{
public void focusGained(FocusEvent fe)
{
tfield2.setCaretPosition(tfield2.getDocument().getLength());
}
public void focusLost(FocusEvent fe)
{
}
});
contentPane.add(tfield);
contentPane.add(tfield2);
setContentPane(contentPane);
pack();
setVisible(true);
}
public static void main(String... args)
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
new TextFieldExample();
}
});
}
}
for #Pete and will be deleted
import java.awt.*;
import javax.swing.*;
import javax.swing.text.DefaultCaret;
import javax.swing.text.DefaultHighlighter;
import javax.swing.text.Highlighter;
public class TestTextComponents extends JFrame {
private static final long serialVersionUID = 1L;
private JTextField jTextField1;
private JTextField jTextField2;
public TestTextComponents() {
initComponents();
}
private void initComponents() {
jTextField1 = new JTextField();
jTextField2 = new JTextField();
getContentPane().setLayout(new FlowLayout());
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
setTitle("Text component persistent selection");
setResizable(false);
getContentPane().add(new JLabel(
"Please skip between text fields and watch persistent selection: "));
jTextField1.setText("jTextField1");
getContentPane().add(jTextField1);
jTextField2.setText("jTextField2");
getContentPane().add(jTextField2);
jTextField1.setCaret(new HighlightCaret());
jTextField2.setCaret(new HighlightCaret());
//Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
// setBounds((screenSize.width - 600) / 2, (screenSize.height - 70) / 2, 600, 70);
}
public static void main(String args[]) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new TestTextComponents().setVisible(true);
}
});
}
}
class HighlightCaret extends DefaultCaret {
private static final Highlighter.HighlightPainter unfocusedPainter =
new DefaultHighlighter.DefaultHighlightPainter(new Color(230, 230, 210));
private static final long serialVersionUID = 1L;
private boolean isFocused;
#Override
protected Highlighter.HighlightPainter getSelectionPainter() {
return isFocused ? super.getSelectionPainter() : unfocusedPainter;
}
#Override
public void setSelectionVisible(boolean hasFocus) {
if (hasFocus != isFocused) {
isFocused = hasFocus;
super.setSelectionVisible(false);
super.setSelectionVisible(true);
}
}
}
How about if you moved the caret to the end?
txt.setCaretPosition(txt.getText().length());

Categories