UndoableEditListener - adding to JLabel and JTextPane - java

I have a 9x9 panel, which is panel1[][]
each panel has a JLabel, so label1[][]
and I add each label to the panel in for loop:
for (int y = 0; y < 9; y++) {
for (int x = 0; x < 9; x++) {
label[y][x] = new Grid(x, y);
panel1[y][x].add(label[y][x]);
}
}
The main goal is to be able to add a addUndoableEditListener() to each of these JLabels.
Users will select a number(int) to place in the JLabel, I want them to be able to undo/redo their selection, by clicking the undo/redo button.
I tried:
UndoManager manager = new UndoManager();
label1.addUndoableEditListener(manager);
However I saw that apprently you cannot add "UndoableEditListener" to JLabels. (Right?)
I saw some examples where you could add "UndoableEditListener" to JTextPane, so I though maybe I could create a JTextPane pane [9][9], and add a textpane to each of the JLabels(which are added to the JPanel). So this would solve the problem of UndoableEditListener.
Does this seem logical? I would really appreciate an easier approach to this, all suggestions welcome : )
I'm just having some problem with adding the UndoableEditListener to the components.
(I would prefer to keep the JLabel, since I need to be able to change the background color feature, otherwise is there a better way??)
Thanks.

It looks like you don't really want a JLabel. If you want it to be editable (and undoable), why not a JTextField?
A JTextField can have its background color changed as well as a JLabel:
JTextField tf = new JTextField();
tf.setColor(Color.RED);

Related

Change JCalendar backgroundcolor

I am trying to change the JCalendar component background color from the component properties itself with no success.
While changing the foreground color from the component proprieties is working fine.
I also tried menuCalendar.setBackground(new Color(135,239,251)) with no success.
Can anyone help?
Setting the background color for JCalendar is surprisingly complicated. There is one convenience method which allows to change part of the calendar's background. You could see if this does what you want first: menuCalendar.setDecorationBackgroundColor(new Color(135,239,251));
This probably won't do what you want. Changing the color of the background behind the day buttons and the colors of the buttons themselves can be changed with the following code. It has to be done this way as JCalendar uses native Swing components which are nested in one another and convenience methods seem to be lacking:
for (int i = 0; i < menuCalendar.getComponentCount(); i++) {
if (menuCalendar.getComponent(i) instanceof JDayChooser) {
JDayChooser chooser = ((JDayChooser) menuCalendar.getComponent( i ) );
JPanel panel = (JPanel) chooser.getComponent(0);
// the following line changes the color of the background behind the buttons
panel.setBackground(Color.BLACK);
// the for loop below changes the color of the buttons themselves
for (int y = 0; y < panel.getComponentCount(); y++) {
panel.getComponent(y).setBackground(Color.BLACK);
}
break; // leave the for loop, we're done
}
}

Is it possible to place components randomly without container in Swing window builder?

The only way, as far as I know, to put a JButton or a JLabel is via creating the GUI structure through Containers and placing those components on it.
Are there other methods to add components randomly into the frame and resize accordingly ,as can be done in Visual C# for example? What is the method to do it?
Yes.
You could use a null Layout and then place components using setBounds().
For example:
JPanel panel = new JPanel(null);
for (int i = 0; i < 4; i++) {
JButton b = new JButton("JButton-"+i);
b.setBounds(50+i*10, 50+i*10, 100, 100);
panel.add(b);
}
If you want random placing, you could random the first 2 (x,y) values.
You will need to provide on your own valid values to be placed inside the parent container.

mixing gridlayout and borderlayout

I was tired but before quitting just stuck in the nearly-last 3 lines in the code snippet below to make a "refresh" button on my tictactoe panel, hoping to get away with it but expecting errors, since it mixes layout managers on a single container.
But it WORKED.
ButtonPanel.setLayout(new GridLayout(3, 3));
guiFrame.add(ButtonPanel);
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
button[i][j] = addButton(ButtonPanel, i, j);
}
}
JButton refreshbutton = new JButton("Refresh");
guiFrame.add(refreshbutton, BorderLayout.SOUTH); // ... border layout worked. Hm.
refreshbutton.addActionListener(this);
guiFrame.setVisible(true); }
Should I be surprised? (Keep in mind my newbieness.)
(BOY, did I learn/stumble onto a buncha stuff in writing this silly game's program!!!--for instance, using setActionCommand to "label" each button internally [as 11,12,13,21,...33] so the ONE actionPerformed method could use getActionCommand to correctly label [with X or O] whatever button was pushed by whoever's turn it was.)
guiFrame.add(refreshbutton, BorderLayout.SOUTH); // ... border layout worked. Hm.
Just because you used BorderLayout.SOUTH does not make a panel a BorderLayout. Your code worked because the default layout manager for the content pane of a JFrame (JDialog) is a BorderLayout. So you are just taking advantage of the default layout.
since it mixes layout managers on a single container.
Yes, this is a common practice. In fact it is almost impossible to create a reasonably complex GUI if you don't use different layout managers on different panels that you add to a GUI.

JScrollPane always clears my Panel

Hy.. I have a JPanel, and in this contentPanel I added some other custom panels and give them locations etc. So now I added a JScrollPane to the contentPanel and always when I scroll down it clears my contentPanel, but the panels are still there but not visible...
How can I make them visible again?
That's my code to add the Panel into the contentPanel. The x,y,j are some settingsstuff for the location because I have an fixed window.
private void reloadContentPanel() {
int x = -200, y = 0, j = 1, row = 4;
EventPanel panel = null;
int i;
for(i=0; i < this.images.size();i++)
{
panel = new EventPanel(this.images.get(i).getAbsolutePath(),
this.images.get(i).getName());
panel.setLocation(x+(j*200), y);
j++;
if(i == row) {
x = -200;
y += 205;
j = 1;
row += 5;
}
this.contentPanel.add(panel);
}
this.repaint();
}
Thanks
it sounds like you are not using a LayoutManager correctly.
after creating your JFrame (i'm guessing within your constructor) add the following (for example):
this.setLayout(new FlowLayout());
this will certainly not be the best layout manager for what you are trying to do but will stop the add calls from overriding the displayed component.
you will need to read further about LayoutManagers
besides this, it's not really advisable to extend JFrame. It's better practice to treat JFrame as a member of your class just like all the other components.
I have the answer! :)
I use a GridLayout not a FlowLayout, so it's fine and it automatically refreshes the panels =)

Java GUI repaint() problem?

I have a JFrame. This JFrame contains a JButton. I click the JButton and 10 JTextFields are created.
the problem:
I cannot see them until "I force a repaint()" by resizing the window. Only then do I see the JTextFields created.
CODE:
JPanel points = new JPanel();
//Creating the JTextFields:
for (int i=0; i<10; i++) {
JTextField textField = new JTextField();
points.add(textField);
}
repaint();
this.repaint();
super.repaint();
points.repaint();
THANK YOU - after the for loop, I just called points.validate() and it worked...
Container.add API docs sayeth:
Note: If a component has been added to
a container that has been displayed,
validate must be called on that
container to display the new
component. If multiple components are
being added, you can improve
efficiency by calling validate only
once, after all the components have
been added.
It's obscure and not very clever, but it's the rules. It may be better to call JComponent.revalidate

Categories