how can I delete element from GridBagElement ?
http://i.stack.imgur.com/1BsDW.jpg
I want to remove the selected item by clicking on the button.
How can I send the name of the selected item as a parameter to the action button?
First, you don't delete from GridBagLayout. With swing you add Components to a Container, and you remove them from a Container.
http://docs.oracle.com/javase/6/docs/api/java/awt/Container.html#remove%28java.awt.Component%29
To select the Green Panel you can Register an ActionListener or MouseListener for this Panel.
The MouseListener delivers the MouseEvent.
The MouseEvent can get you the Source with getSource, which is the green Panel.
And that panel can be removed.
A simple example snippet:
final JPanel mainPanel = new JPanel();
JPanel greenPanel = new JPanel();
greenPanel.addActionListener(new ActionListener(){
#Override
public void ActionPerformed(ActionEvent e){
int answer = JOptionPane.showConfirmDialog(null, "Delete?");
if(answer == JOptionPane.YES_OPTION){
mainPanel.remove(e.getSource());
}
}
});
mainPanel.add(greenPanel);
You will want to establish some kind of contract between things like buttons and other controls and your view.
Things that want to modify the view should not be able to do anything you don't want them to (like change the layout for instance).
I'd recommend creating a simple interface which provided access to the operations you want external controls to have access to (like adding, editing, removing). This you would pass to your controls, there by restricting what the controls can actually do and not exposing unnecessary functionality to them (you wouldn't one of them to remove you main panel ;)).
When you want to remove a selected task, you click the appropriate button, it calls the appropriate "remove" method on your model.
You implementation would then find the selected item (which I assume you either maintain a reference to or have some means to find) and simply remove it from it's parent container.
Related
I have a JFrame named MainGUI. Inside of MainGUI I have passed three LinkedList ll1, ll2, ll3.
These LinkedList are full of data and I'm trying to just print one of them on the screen into my JPanel. I'm use to just doing a for loop and using System.out.println to print things out onto the screen.
So right now I have MainGUI which hosts three buttons.
New Tasks In Progress Tasks Completed Tasks
Each button has a different LinkedList ll1, ll2, ll3 etc.
I want to be able to click the button and have the data elements listed below in the JPanelI created which rests under the buttons.
Any help is deeply appreciated.
Since you provided no code, I assume you are having trouble understanding how LinkedList can interact in programs that have a GUI.
First off, when using buttons you always need to instruct them to do something when they are clicked by adding an ActionListener, as explained in this answer.
Secondly, if you want to add the list data to the JPanel, there are a few ways you can do it. A JList, or if you'd like the user to be able to copy and paste the data (I find it to be very handy), a JTextArea, ... Just make sure to call setEditable(false) in order to stop the user from fiddling with the data you provide. Considering a JTextArea, here's what that would look like, if ll1 contained Strings:
Adding somewhere that our JPanel contains a JTextArea:
JTextArea txtArea = new JTextArea();
txtArea.setEditable(false);
panel.add(txtArea);
Now, we order the button to do something when clicked:
btn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
txtArea.setText(null); //clear out old text
for(String str: ll1) {
txtArea.append(str+"\n");
}
panel.revalidate(); //repaint JPanel
}
});
This way, you can click the button as many times as you want. Note that if you add more content to ll1 after it is displayed it won't get visually updated by itself, you will always need to click the button again or look further into Listeners.
You can try adding a JTextArea or whichever JComponent that suits what you want to display to the JPanel that you want to display the data from. Write the data from your linked list to that JComponent using its method e.g. append() if you're using JTextArea.
I am trying to set gmailPasswordField.setVisible(true) & senderPasswordLabel.setVisible(true) if the JTextField is changed, but it's not working.
doc.addDocumentListener(
new DocumentListener() {
public void changedUpdate(DocumentEvent e) {
int minLengthEmail = "n#gmail.com".length();
if (countDocumentChangeLength > minLengthEmail) {
gmailPasswordField.setVisible(true); // Doesn't appear to do anything
senderPasswordLabel.setVisible(true); // Nor this
}
}
});
Did you add a System.out.println(...) to see if the code is being executed? This is a basic debugging technique to see if the code is executing as you expect.
The changedUpdate(...) method is invoked when you change an attribute of the text.
I suspect you want to implement the other DocumentListener methods so you will be notified when the "text" in the Document changes. Read the section from the Swing tutorial on How to Write a DocumentListener for more information and working examples.
Don't use the method setVisible(boolean). Use CardLayout instead.
Little howto:
Move your widgets, which visibility must be switched, into a new JPanel (layout panel).
Create another JPanel with CardLayout (card panel) and place the layout panel into it.
Place an empty JPanel into the card panel.
Make sure that the appropriate card is visible (in your case - the empty card).
Make another card visible when required (in your document listener).
I added my buttons in a JPanel (which has a border layout, added the buttons to its south position), then added another JPanel cardsPanel in the (center position of the) parent panel, and gave it a CardLayout. I want this cardsPanel to be the container for the cards (I mean the panels which will share the same screen space).
Now what I need to do is to to display those cards (I am calling the panels which will share the same screen space as cards) as a response to the buttons in the parent panel. But the buttons are located in the parent panel and their action listeners will obviously be located there too.
So the question is that how do I show (by cardLayout.show()) the panels located in a container class (with Cardlayout) as a response to buttons located in another class (with BorderLayout) ?
EDIT - QUESTION ABOUT ACTION:-
I hope to find implementing an Action more useful than an ActionListener. I also read that they can be reused, and used for the buttons which perform the same function. I have a few buttons which perform the function of flipping a particular card (i.e. displaying a particular panel in the CardLayout). I have written just one inner class and I want to use it for all the buttons.
So I will like to pass the button identifier (the string used to identify a button when we add the button to its parent e.g. String btnIdentifier= "1"; panel.add(button1, btnIdentifier); ) to the method actionPerformed() of this class, eventhough we are never explicitly calling actionPerformed(). So how can I pass the string identifier of the button to the actionPerformed() method so that I can use the same Action for all my buttons.
Minimal Code:-
class Action extends AbstractAction{
Action(String text, ImageIcon icon){
super(text, icon);
}
public void actionPerformed(ActionEvent e) {
button1.setBorderPainted(true);
button1.setContentAreaFilled(true);
if (btnIdentifier=="1"){ //////ASSUMING THAT BUTTON IDENTIFIER HAS SOMEHOW BEEN PASSED TO THIS METHOD
FirstCard firstCard= new FirstCard();
cardsPanel.add(firstCard, btnIdentifier);
cardLayout.show(cardsPanel, btnIdentifier);
} else if (btnIdentifier=="2"){ //////ASSUMING THAT BUTTON IDENTIFIER HAS SOMEHOW BEEN PASSED TO THIS METHOD
SecondCard secondCard= new SecondCard();
cardsPanel.add(secondCard, btnIdentifier);
cardLayout.show(cardsPanel, btnIdentifier);
} else if (btnIdentifier=="3"){ //////ASSUMING THAT BUTTON IDENTIFIER HAS SOMEHOW BEEN PASSED TO THIS METHOD
ThirdCard thirdCard= new ThirdCard();
cardsPanel.add(thirdCard, btnIdentifier);
cardLayout.show(cardsPanel, btnIdentifier);
}
}
}
}
Use Action to encapsulate the desired functionality. Make a reference to the enclosing panel visible, as shown here and here; or export the Action from a class having (at least) package-private access, as shown here.
It was hard to word the title for this one, but here's the explanation:
I have a menu bar that I'm adding as an external object from my MenuBar.java that extends JMenuBar to my main program file APP.java that extends JFrame.
MenuBar and a JPanel (which is in my main program file, APP.java) are added to the JFrame. How do I make buttons from the MenuBar perform actions on the JPanel.
Here's how my JMenuItem objects look like right now in MenuBar.java:
item = new JMenuItem("New);
item.setMnemonic(KeyEvent.VK_N);
item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_N,
ActionEvent.ALT_MASK));
item.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
JLabel block = new JLabel();
block.setPreferredSize(new Dimension(120, 160));
//***This is where I run into a problem... I want to add this JLabel to my JPanel in
// the main file, and I also want to revalidate/repaint the JPanel to take show
// the new JPanels as they're added.....
}
});
file.add(item);
I'm not sure if I need to extend my APP to implement ActionListener.... but then I am not sure what to do afterwards.
EDIT:
Well, I was able to perform the intended action by making my content panel public and static, thus making it available without instantiating the APP object. And then I was able to implement this code into my actionPerormed methods in ActionListeners:
APP.content.add(new Thumb());
APP.content.validate();
Thumb() method creates a new JLabel;
Hopefully this won't mess up my stuff later on down the line, being that my content panel is static now.
This is hard to answer.
I would use setAction(Action) (indirectly). One can make an Action as child of AbstractAction, and an Action can hold its text, an icon, mnemonic key and more.
One typical usage is a JTextPane that provides a Action[] getActios() and those actions might be added to the menu bar or a JToolBar.
Please look up some code samples.
I leave it at this half of an answer.
An intro.
It would depend on what actions you want to perform, but the overall solution is the same. You need to pass a reference of the object of the object you want to work with to the menu class.
If you can, its better to pass a model of interace, limiting your actions to only performing work you really want them to
Is it possible to use a single JPanel for multiple tab items in JTabbedPane?
EG:
JTabbedPanel tabs=new JTabbePanel();
JPanel panel=new JPanel();
JButton but=new JButton("TEXT");
but.addActionlistener(this);
panel.add(but)
tabs.add("First",panel);
tabs.add("Second",panel);
An ActionListener is added to the JTabbedPane to notify the program of tab changes (change cur_tab to tab number)
public void actionPerformed(..)
{ System.out.println("Now in "+cur_tab); }
The same component cannot be used for several tabs
taken from here
Sounds like you need a subclass of JPanel. Just create an abstract class that handles the complex layout and have the subclasses create the necessary GUI elements that are required.
If you are just inserting a single text box, button, etc, you may not even need subclasses per tab. Just create multiple instances of the base class and add the component you need.
New panels and other GUI items are relatively cheap. Performance issues in a Swing GUI are more likely to come from event handling or firing too many events rather than how complex or how many components it has. Make things easier to maintain and understand, then worry about performance.
if you'll create class that returns JPanel then yes that's possible
but Notice:
there are long time Bug that two Tabs can't contains same component schemas, with schemas I means for example one Tab contains JPanel + JTextField + JButton, but then second JPanel must contains another Numbers or Type of JComponents
unfortunatelly (nothing special) BugsDatabase isn't accesible in this moment
I had a panel with memory-intensive components on it which I only wanted to create one instance of, but change the behaviour of it using the attractive JTabbedPane.
I did it by creating empty panels for each tab, and a third panel that contains my (single) complicated components. On the StateChange event for the JTabbedPane, I remove the third panel from whichever of the first two it was in, and add it to whichever one is newly selected.
Bit hacky, but it works fine.
You are wrong.
Just set a panel on the first tab in function initComponents() like that:
p.add("1", MainPanel);
Then use:
p.add("2", p.getTabComponentAt(0));
Using this metode you will have the same component on 2 tabs.
You can use StateChanged Event to change actions in this tabs.
For example:
JTabbedPane p = (JTabbedPane)Tabbar;
int idx = p.getSelectedIndex();
if(idx==0){
Do something...
}
if(idx==1){
Do something different...
}
The following will allow you to add the same component with different titles to a JTabbedPane:
JTabbedPane tabbedPane = new JTabbedPane()
{
boolean adding = false;
#Override
public void removeTabAt(int index)
{
if(!adding)
{
super.removeTabAt(index);
}
}
#Override
public void insertTab(String title, Icon icon, Component component, String tip, int index)
{
adding = true;
super.insertTab(title, icon, component, tip, index);
adding = false;
}
};