Tabbing over a JTable component - java

I have a panel containing a number of components, one of which is a JTable. When the JTable has focus and the TAB key is pressed, the default behaviour is to move focus from cell to cell within the table. I need to change this to focus on the next component instead i.e. leave the JTable completely.
Ctrl-TAB achieves the desired results, but is not acceptable to the user. I can add a key listener to the table and change the focus when TAB is pressed, but it feels as though there might be a better way to do this.
Any ideas?
Thanks...

You would typically do this by adding an Action to the components action map and then binding a keystroke with it in the component's input map (example code below). However, this will not work for tab as this event is consumed by the focus subsystem unless you add the following line to remove tab as a focus traversal key:
tp.setFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, Collections.<AWTKeyStroke>emptySet());
Here's the full example code:
public static void main(String[] args) {
final JTabbedPane tp = new JTabbedPane();
// Remove Tab as the focus traversal key - Could always add another key stroke here instead.
tp.setFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, Collections.<AWTKeyStroke>emptySet());
KeyStroke ks = KeyStroke.getKeyStroke(KeyEvent.VK_TAB, 0);
Action nextTab = new AbstractAction("NextTab") {
public void actionPerformed(ActionEvent evt) {
int i = tp.getSelectedIndex();
tp.setSelectedIndex(i == tp.getTabCount() - 1 ? 0 : i + 1);
}
};
// Register action.
tp.getActionMap().put("NextTab", nextTab);
tp.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(ks, "NextTab");
tp.addTab("Foo", new JPanel());
tp.addTab("Bar", new JPanel());
tp.addTab("Baz", new JPanel());
tp.addTab("Qux", new JPanel());
JFrame frm = new JFrame();
frm.setLayout(new BorderLayout());
frm.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frm.add(new JButton(nextTab), BorderLayout.NORTH);
frm.add(tp, BorderLayout.CENTER);
frm.setBounds(50,50,400,300);
frm.setVisible(true);
}

Well you probably don't want to just get rid of the Tab Action because it has other responsibilities. For example, when you are editing a cell the Tab Action stops cell editing before moving to the next cell. So you probably want to retain this behaviour while adding extra behavour to change focus to the next component.
I refer to this as "wrapping an action" and you can find an example of this by checking out the Table Tabbing action. You should be able to easily customize the code to use the KeyboardFocusManager to transfer focus.

Related

How can i refresh a JDialog Image Correctly?

i am coding a program using SWing in java, but this is my problem, when i press a button, I want that every time I press a button, I update a new image in the same position as the previous one, I try to do it in the action listener of the code, but the image is not updated and the one that was At the beginning, can someone help me in this? Thank you very much.
public MainWindow() {
initComponents();
setIconImage(Icono);
this.setLocationRelativeTo(null);
this.setResizable(false);
Imagen fondo=new Imagen();
this.add(fondo, BorderLayout.CENTER);
this.pack();
PracticeMode = new javax.swing.JDialog();
}
private void StartPracticeActionPerformed(java.awt.event.ActionEvent evt) {
ButtonsSelected(1);
StartGame Practice=new StartGame(OpcComboBox, numUnity, numTrys,
opcNotas, false);
PracticeBF.dispose();
PracticeMode.setIconImage(Icono);
PracticeMode.setBounds(460, 600, 460, 538);
PracticeMode.setVisible(true);
CirculodeQuintasBW BW=new CirculodeQuintasBW();
PracticeMode.add(BW, BorderLayout.CENTER);
PracticeMode.pack();
PracticeMode.setLocationRelativeTo(null);
PracticeMode.setResizable(false);
}
This is the Image that i want to refresh, it supossed to be another Image before of that, but each time i tried to refresh it doesnt work...
PracticeMode it supossed to be a JDialog, anybody can help me?.
private void D2ActionPerformed(java.awt.event.ActionEvent evt) {
CirculodeQuintasD D=new CirculodeQuintasD();
PracticeMode.add(D, BorderLayout.CENTER);
PracticeMode.validate();
PracticeMode.repaint();
PracticeMode.pack();
}
First of all variable names and method names should NOT start with an upper case character. Learn by example from reading your text book or tutorial and then follow the Java conventions and don't make up your own!
when i press a button, I want that every time I press a button, I update a new image in the same position as the previous one,
Add an JLabel containing an ImageIcon to your panel.
When you want to change the image you just use:
label.setIcon( new ImageIcon(...) );
For example read the section from the Swing tutorial on How to Use Combo Boxes. It does exactly what your want. It uses an ActionListener to change the image of a label. The only different is that the ActionEvent is generated by clicking on an item in the combobox instead of clicking on a button.

How to align text position for two different components?

I am trying to align the position of text within a JTextArea and a JButton, but with everything I tried, either nothing happens, or the alignment is still slightly off.
Here is what is looks like:
(You can see with the highlighted option that the JButton (center) is slightly lower than the two JTextAreas on either side.)
Here is some code:
categoryFile[i][j] = tempButton;
categoryFile[i][j].setBackground(Color.white);
categoryFile[i][j].setForeground(Color.black);
categoryFile[i][j].setOpaque(true);
categoryFile[i][j].setFocusable(false);
categoryFile[i][j].setBorderPainted(false);;
categoryFile[i][j].setVerticalAlignment(SwingConstants.TOP);
categoryFile[i][j].setPreferredSize(new Dimension(500,10));
categoryFile[i][j].addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
openPDFWithOptions(filePath,fileName);
}
});
JPanel listRow = new JPanel();
listRow.setBackground(Color.white);
listRow.setLayout(new BorderLayout());
listRow.setPreferredSize(new Dimension(800, 40));
JTextArea category = new JTextArea(fileElements[0]);
category.setEditable(false);
JTextArea parent = new JTextArea(fileElements[1]);
parent.setEditable(false);
listRow.add(parent,BorderLayout.WEST);
listRow.add(categoryFile[i][j],BorderLayout.CENTER);
listRow.add(category,BorderLayout.EAST);
categoryLists[i].add(listRow,c);
Right now I am using categoryFile[i][j].setVerticalAlignment(SwingConstants.TOP) to change the position of the JButton, which ALMOST works. I've also tried changing the vertical alignment of the JTextAreas, but nothing changed.
How can I align the text within these components?
Quickest way to fix this would probably be to just add some padding on the 1st and third columns to set all the text to the same height. See Jpanel Padding

populating JTabbed Pane with JScroll panes according to user selection

We have a project for university which is a program to hold handouts and feedback for courseworks done.
What we've thought of is breaking the whole thing down into smaller pieces, for example:
You have a coursework which requires to write a program and a report on results etc.
So the user will create a new coursework by selecting the "code" and "report" options, since that's what is required. And then we need to create the respective tabs in the program so the user can input what is needed.
I have created all necessary forms and windows, It's just I'm not sure how to move on forward.
a) where should I put my code? should I have it on the "create" event?
b) how do I do this whole custom population thing?
Obviously, I'm not asking for the entire thing in code. I'm not even sure what to read and what to search for.
Following are some screenshots of the ui to help explain what I mean.
New project window
How the main window should be after creating a new projet. Notice the various tabs.
A form for report feedback
On your "Create" button click check for the checkbox.isSelected() and use the method below as:
if(reportCheckbox.isSelected()){
addonScreen(new reportFrame(),"Report Submission");
addonScreen(new reportFeedbackFrame(),"Report Feedback");
}
Use a desktop pane as a container...add your tabbed pane to it
public static JTabbedPane tabbedPane = new JTabbedPane();
jDesktopPane1.add(tabbedPane);
Use this method to add tabs to the layout at runtime
public static void addOnScreen(JInternalFrame inFrame, String title) {
//border for the internal frame
javax.swing.plaf.InternalFrameUI ifu = inFrame.getUI();
((javax.swing.plaf.basic.BasicInternalFrameUI) ifu).setNorthPane(null);
Border b1 = new LineBorder(new Color(114, 139, 173), 3, true) {
};
tabbedPane.setBounds(0, 0, jDesktopPane1.getWidth(), jDesktopPane1.getHeight());
inFrame.setLocation(0, 0);
inFrame.setSize(jDesktopPane1.getWidth(), jDesktopPane1.getHeight());
inFrame.setBorder(b1);
JPanel jp = new JPanel();
jp.setLayout(new GridLayout());
jp.setOpaque(true);
jp.add(inFrame);
tabbedPane.addTab(title, jp);
tabbedPane.setSelectedComponent(jp);
inFrame.requestFocusInWindow();
inFrame.setVisible(true);
tabbedPane.setVisible(true);
}

disable mouseEvent for a specific JButton in a group of JButtons

The flow of the program is like this : Image from 1st set of buttons (leftButtonArea) is dragged to the 2nd set of buttons (rightButtonArea).
Each image has a unique name via setName(). The name of the image that was dragged over will be compared with the name of the button which it is dragged to.
If the name matches, I wish to disable that particular button from reacting to any hover event.
.setHoverEnabled(false) doesn't work =/
A similar SO thread regarding the disabling of event listeners, but it seems like the solutions such a using a glass pane are for whole components ?
link
Edit:
Somehow this works, but I am not sure of any side effects from this method
source.removeMouseListener(source.getMouseListeners()[1]);
Edit2:
Found something interesting.. This could be the reason why disabled buttons still reacts to mouseEvents.
"low-level: Component, Container, Focus, Key, Mouse, Paint, Window
semantic: Action, Adjustment, Item, Text
Only semantic events are affected by disabling any component. That is because they are directly handled by the component itself which is aware that it is enabled or not.
Low level events can't be affected by disabling. If you stop to think about this when you disabled your label was it still visible. If it was then the paint event must have happened. Low level events will always happen and it is up to your handlers to query the component if it is enabled or not."
// 1st set of 4 buttons
for(int a=0; a<4; a++){
leftButtonArea[a] = new JleftButtonArea(new ImageIcon(image));
TransferHandler transfer = new TransferHandler("icon");
leftButtonArea[a].setTransferHandler(transfer);
leftButtonArea[a].addMouseListener(new MouseAdapter(){
public void mousePressed(MouseEvent e){
JleftButtonArea leftButtonArea = (JleftButtonArea)e.getSource();
TransferHandler handle = leftButtonArea.getTransferHandler();
handle.exportAsDrag(leftButtonArea, e, TransferHandler.COPY);
// get unique name for the image that is dragged
// to rightButtonArea
name1 = e.getComponent().getName();
}
});
}
// creates 2nd set of 4 buttons
for(int b=0; b<4; b++){
rightleftButtonAreaArea[b] = new JleftButtonArea();
// <---- creates unique name for each leftButtonArea ----->
cc2 += 1;
id2+="a"+cc2;
rightleftButtonAreaArea[b].setName(id2);
// <---- creates unique name for each leftButtonArea ----->
TransferHandler transfer1 = new TransferHandler("icon");
rightleftButtonAreaArea[b].setTransferHandler(transfer1);
rightleftButtonAreaArea[b].addMouseListener(new MouseAdapter(){
#Override
public void mouseExited(MouseEvent me){
JleftButtonArea source = (JleftButtonArea)me.getSource();
try{
// compare unique name of image and the button in rightButtonArea
// if they are the same, disable hover for the button
if( name1.equals(source.getName())){
// this doesn't work
source.getName().setHoverEnabled(false);
// Somehow this works, but I am not sure of any side effects from this
source.removeMouseListener(source.getMouseListeners()[1]);
}
else{
source.setIcon(null);
}
}
catch (NullPointerException e)
{
}
}
});
}
for Buttons JComponents are MouseEvent are implemented in the ButtonModel
use implemented methods for Icon in the JButton API
examples JButton & Icon, JButton & ButtonModel
try
button.setRolloverEnabled(false);

Add & remove JTextField at runtime in Java(Swings) program

how to add and remove components(JButons , JTextField etc) at runtime in a Swing program (Java ) , without using NetBeans ? which Layout should I use ?
I want the user to enter Username & Password and , when he clicks on Submit button , the new screen with new components(JButtons , JTextField etc) should appear , I am unable to achieve the transition at runtime.
You want to use two different panels to achieve this result. It's not a good idea to use the same panel and remove all of the first components and add all of the second ones.
Make a LoginPanel class which lays out the username and password fields, labels, and submit button. Then, when the submit button is pressed, after the login is authenticated, hide the login panel and display a new panel with the layout you want for the next screen.
This sort of approach makes it much easier to maintain the two panels, and clearly separates their layouts and functionality from each other.
You can center this new frame over the existing panel using this code:
public static void centerFrameOverComponent(JFrame frame, JComponent component) {
Window parent = SwingUtilities.getWindowAncestor(component);
Rectangle frameRect = frame.getBounds();
Rectangle parentRect = parent.getBounds();
int x = (int) (parentRect.getCenterX() - frameRect.getWidth() / 2);
int y = (int) (parentRect.getCenterY() - frameRect.getHeight() / 2);
frame.setLocation(x, y);
}
Another approach is to call setVisible(false) on the specific component when you wish to hide it.
In cases where I have wanted to add/remove an entire sub panel, I have used the following:
panel.remove(subPanel);
panel.revalidate();
panel.repaint();
You want to call the last two methods whenever you add/remove components.
One approach would be to use CardLayout. Your login button handler would check the credentials and use show() to reveal the second pane.
Addendum: For security, consider using JPasswordField for the password; for convenience, consdier setLocationRelativeTo() for positioning the frame.
you could create a new class for exsample MyFrame thath extends JFrame, that rapresetns your new windows, in the constructor of that class you have to add at the contentpanel your all contolr....
in this way you can add a jbutton to your JFrame.
class MyFrame extends JFrame{
private JButton jb= new JButton("hello");
public MyFrame(){
setSize(new Dimension(300,180)); //set the MyFrame size
getContentPane().add(jb); //add your Component at ContentPane
}
}
after the login you could show your new frame in this way:
new MyFrame().setVisible(true);

Categories

Resources