So this snippet of code is from an application I'm building for my job. One window gets the user's name, then they select a category, then they take the quiz.
static void QuestionsWindow(){
ProtemInservices.SetActiveQuestions();
JFrame frame = new JFrame("Quiz for: " + ProtemInservices.testeeName);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Vector<JLabel> questions = new Vector<JLabel>();
Vector<ButtonGroup> questionsGroup = new Vector<ButtonGroup>();
Vector<JRadioButton> choices = new Vector<JRadioButton>();
Vector<String> choicesString = new Vector<String>();
frame.setLayout(new BoxLayout(frame.getContentPane(), BoxLayout.Y_AXIS));
int counter = 0;
for(int i=0;i<ProtemInservices.ActiveQuestions.size();i++){
choicesString = new Vector<String>();
questions.add(new JLabel(ProtemInservices.ActiveQuestions.elementAt(i).GetQuestionText()));
ProtemInservices.ActiveQuestions.elementAt(i).CopyChoices(choicesString);
questionsGroup.add(new ButtonGroup());
frame.add(questions.elementAt(i));
for(int j=0;j<choicesString.size();j++,counter++){
choices.add(new JRadioButton(choicesString.elementAt(j)));
questionsGroup.elementAt(i).add(choices.elementAt(j));
frame.add(choices.elementAt(counter));
}
}
frame.setMinimumSize(new Dimension(1280, 1024));
//Display the window.
//frame.pack();
frame.setVisible(true);
}
My problem is dynamically creating RadioButtons and Labels. The labels come out as expect, but the nested loop is supposed to create a set of RadioButtons for each Label. I have only tested this with two different categories, the first creates the labels then creates the RadioButtons, but only for the first label and after it has created all other labels. The second category creates the labels as it should but the RadioButtons are real wonky, two come after the second label and another two are at the end.
First Category GUI
Any hints would be extremely appreciated.
static void QuestionsWindow(){
ProtemInservices.SetActiveQuestions();
JFrame frame = new JFrame("Quiz for: " + ProtemInservices.testeeName);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Vector<JLabel> questions = new Vector<JLabel>();
Vector<ButtonGroup> questionsGroup = new Vector<ButtonGroup>();
Vector<JRadioButton> choices = new Vector<JRadioButton>();
Vector<String> choicesString = new Vector<String>();
frame.setLayout(new BoxLayout(frame.getContentPane(), BoxLayout.Y_AXIS));
int counter = 0;
for(int i=0;i<ProtemInservices.ActiveQuestions.size();i++){
choicesString = new Vector<String>();
questions.add(new JLabel(ProtemInservices.ActiveQuestions.elementAt(i).GetQuestionText()));
ProtemInservices.ActiveQuestions.elementAt(i).CopyChoices(choicesString);
questionsGroup.add(new ButtonGroup());
frame.add(questions.elementAt(i));
for(int j=0;j<choicesString.size();j++,counter++){
choices.add(new JRadioButton(choicesString.elementAt(j)));
questionsGroup.elementAt(i).add(choices.elementAt(counter));
frame.add(choices.elementAt(counter));
}
}
frame.setMinimumSize(new Dimension(1280, 1024));
//Display the window.
//frame.pack();
frame.setVisible(true);
}
The logic is laid out above in the comments on how we came to this solution.
Related
I am currently trying to make a JFrame which should contain one String followed by a text entry field for each entry in a HashMap (longToShortNamesMap). Currently I am displaying the entries as follws in a JOptionPane:
String paneMessage = "";
List keys = new ArrayList(longToShortNameMap.keySet());
for(int i = 0 ; i < keys.size();i++){
paneMessage += "Field name " + keys.get(i) + " has been shortened to " + longToShortNameMap.get(keys.get(i)) + "\n";
}
JOptionPane.showMessageDialog (null, paneMessage, "Data Changed", JOptionPane.INFORMATION_MESSAGE);
Instead, I would like a frame to appear which will have the same message appear but will have the "longToShortNameMap.get(keys.get(i))" part appear in an editable text field. I'm not quite sure how ot go about this but this is what I have so far which is popping one JFrame with one label (which is not an editable text field).
private static void showFrames(Map<String,String> longToShortNameMap) {
JFrame frame = new JFrame("Data Changed");
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.setSize(400, 500);
frame.setResizable(true);
frame.setLocationRelativeTo(null);
JPanel panel = new JPanel(new BorderLayout());
List<String> keys = new ArrayList(longToShortNameMap.keySet());
for (String key : keys) {
JLabel label = new JLabel(longToShortNameMap.get(key));
panel.add(label);
}
frame.add(panel);
}
EDIT: As a contextual side note, I am doing this because field names are limited to 10 characters in a place in my application so I am forced to trim the field names down to 10 characters. When I do this, I want to notify the user what each trimmed field has been trimmed to and additionally give them the option to change the trimmed named
Your main issue is your choice of layout manager. BorderLayout allows one component in each of its 5 areas. When you're adding your labels to the center area (the default), you keep replacing the last one instead of appending it. I recommend adding each label and JTextField (your editable field) to a GridLayout panel.
private static void showFrames(Map<String,String> longToShortNameMap) {
JFrame frame = new JFrame("Data Changed");
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.setSize(400, 500);
frame.setResizable(true);
frame.setLocationRelativeTo(null);
JPanel panel = new JPanel(new GridLayout(0, 2)); //use gridlayout
List<String> keys = new ArrayList(longToShortNameMap.keySet());
for (String key : keys) {
JLabel label = new JLabel(key); // your label is the key itself
JTextField textField = new JTextField(longToShortNameMap.get(key));
panel.add(label); // Populate textfield with the key's value
panel.add(textField);
}
frame.add(panel);
}
I received in loop iteration as:
Tab 1
Tab 2
On beginning code I have panel, tabbedpane and scrollpane:
JPanel panel = new JPanel();
JTabbedPane tabbedPane = new JTabbedPane();
JScrollPane scrollPanel = new JScrollPane();
Then receive through iteration using Event JList and receive Tab 1 and Tab 2, but can't add two tabs. So here is iterate and receive Tab 1 and Tab 2 into tab_name variable:
String tab_name = ap_data_array[2]; // Tab 1, Tab 2
tabbedPane.addTab(tab_name, panel); // Here add only once tab Tab 1
this.jPanel1.add(tabbedPane, BorderLayout.CENTER);
scrollPanel.setViewportView(new JLabel(ap_data_array[2]));
tabbedPane.setBounds(0, 0, 530, 500);
this.jPanel1.setSize(530,500);
System.out.println(tab_name); // Tab 1 then Tab 2
A result will only render 1 tab, Tab 1.
Here is full code:
String lines[] = loaded_data.split("\\r?\\n");
for (String item : lines)
{
String pattern = "AP.*";
Pattern r = Pattern.compile(pattern);
Matcher m = r.matcher(item);
// Added
JPanel panel = new JPanel();
JTabbedPane tabbedPane = new JTabbedPane();
JScrollPane scrollPanel = new JScrollPane();
if (m.find())
{
String ap_data = m.group(0);
String[] ap_data_array = ap_data.split("\\|", -1);
if (ap_data_array[0].equals("AP"))
{
JList source = (JList)evt.getSource();
String selected = source.getSelectedValue().toString();
// type selected
if (ap_data_array[1].equals(selected))
{
// tabs name
//ap_data_array[2] // "Tab 1" "Tab 2"
String tab_name = ap_data_array[2];
tabbedPane.addTab(tab_name, panel);
this.jPanel1.add(tabbedPane, BorderLayout.CENTER);
scrollPanel.setViewportView(new JLabel(ap_data_array[2]));
tabbedPane.setBounds(0, 0, 530, 500);
this.jPanel1.setSize(530,500);
System.out.println(tab_name); // "Tab 1" "Tab 2"
}
}
}
}
SOLUTION:
private void jList1ValueChanged(javax.swing.event.ListSelectionEvent evt) {
if (evt.getValueIsAdjusting())
{
JTabbedPane tabbedPane = new JTabbedPane();
this.jPanel1.removeAll(); // REMOVE ALL DATA IN PANEL TO RELOAD NEW TAB PANEL IN LOOP
String lines[] = loaded_data.split("\\r?\\n");
for (String item : lines)
{
String pattern = "AP.*";
Pattern r = Pattern.compile(pattern);
Matcher m = r.matcher(item);
JPanel panel = new JPanel();
if (m.find())
{
String ap_data = m.group(0);
String[] ap_data_array = ap_data.split("\\|", -1);
if (ap_data_array[0].equals("AP"))
{
JList source = (JList)evt.getSource();
String selected = source.getSelectedValue().toString();
// type selected
if (ap_data_array[1].equals(selected))
{
String tab_name = ap_data_array[2]; // STRING "Tab 1" and "Tab 2" loop
this.jPanel1.add(tabbedPane, BorderLayout.CENTER);
tabbedPane.add(tab_name, new JLabel(tab_name));
tabbedPane.setBounds(0, 0, 530, 500);
this.jPanel1.setSize(530,500);
}
}
}
}
}
}
If I understand your code correctly (no guarantee since it's not a minimal example program that I can run and test), inside of the for loop you're creating a new JTabbedPane with each iteration, adding a single tab to it, and then adding it to a BorderLayout-using JPanel in the BorderLayout.CENTER position. Thus if you iterate twice, you will create two JTabbedPanes, each with only one tab, and the second one will completely cover the first one. If this is indeed the source of your problems then the solution is easy: create only one JTabbedPane, do this before the for loop, and add your tabs (JPanels) inside the for loop.
Other problems include your use of setBounds(...). Don't do this.
I have a JList in my GUI, which uses an ArrayList as data:
ArrayList Cruise = new ArrayList();
Cruise.add("Scottish to Greek Waters");
Cruise.add("Greek to Scottish Waters");
JScrollPane scrollPane = new JScrollPane();
CruiseList = new JList(Cruise.toArray());
CruiseList.setPreferredSize(new Dimension(200, 200));
scrollPane.setViewportView(CruiseList);
CruiseList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
CruiseList.setSelectedIndex(0);
CruiseList.setVisibleRowCount(6);
listPanel.add(scrollPane);
Frame1.setVisible(true);
I have a button - List all Cruises, which once clicked on should display this as output:
"Scottish to Greek Waters"
"Greek to Scottish Waters"
However, upon clicking the button, it only displays the selected list option as output.
This is what I have so far:
listallCruises.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
String AllCruises = CruiseList.getSelectedValue().toString();
System.out.print("All Cruises:\n" + AllCruises + CruiseList.getModel() + "\n");
}
});
How do I print out all element in the list upon clicking the button?
You are outputting just the selected value because that's the method you are calling, getSelectedValue().
To display ALL the values, you have to get the model and iterate through the values, like so:
int size = CruiseList.getModel().getSize();
StringBuilder allCruises = new StringBuilder("All cruises:");
for(int i = 0; i < size; i++) {
allCruises.append("\n").append(CruiseList.getModel().getElementAt(i));
}
System.out.print(allCruises);
I create a button that will onclick show in a separate window (like you see below) the list of all users from my database.
But, they are displayed all in one line! Even though I put /n - it just wont work. I mean, it work in console when I use Sys.out but when I go to the Window and put it there it is all in one line :(
What should I change in order to display all of the users one below another.
public class ViewAll {
private String listax = "";
ViewAll() throws ClassNotFoundException, InstantiationException, IllegalAccessException, SQLException{
ArrayList<String[]> allUsers = DbBroker.getArray("select * from user");
for(String[] usr : allUsers)
listax += usr[0] + ")" + usr[1] + ", " + usr[2] + ", " + usr[3] + "\n";
}
public void display() {
JFrame lis = new JFrame("List of all users");
lis.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
lis.setLayout(new FlowLayout(FlowLayout.LEFT));
JPanel pane = new JPanel(new GridLayout(0,1));
lis.add(pane);
pane.add(new JLabel("This is the complete list of all users in my db: "));
pane.add(new JLabel(listax));
lis.pack();
lis.setSize(500,400);
lis.setVisible(true);
}}
I suggest that you don't use a JLabel but instead use a JList. It was built to do just this sort of a thing. The key here being: use the right tool for the job. It also appears that you're trying to use a JFrame in a dialog capacity, and if so, don't -- use a JDialog instead, or even a JOptionPane:
public void display(List<String> userList) {
DefaultListModel<String> listModel = new DefaultListModel<String>();
for (String user : userList) {
listModel.addElement(user);
}
JList<String> userLabel = new JList<String>(listModel);
JScrollPane scrollPane = new JScrollPane(userLabel);
String title = "This is the complete list of all users in my db:";
// mainJFrame is the main JFrame for the GUI
JOptionPane.showMessageOption(mainJFrame, scrollPane, title,
JOptionPane.PLAIN_MESSAGE);
}
I am trying to add values to a Jtable, the values are fetched from arrayList,
How do you do that
I tried making Object[][] data; and the populate it inside a loop, but it does not work, How do you fix this?
String[] columns = {"Field String","Field Double"," Field Double"};
Object[][] data;
Iterator<Node> itr = arrayList.iterator();
while (itr.hasNext()) {
Node el = itr.next();
double a = el.getval();
data[i][1] = el.getstring();
data[i][2] = a;
data[i][3] = a*4;
i++;
}
JFrame frame = new JFrame("Title ");
JTable tablE = new JTable(data, columnas);
JPanel panel = new JPanel();
panel.add(table);
frame.add(panel);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(500, 500);
frame.setVisible(true);
How do you populate "data" inside a while loop?
Use a DefaultTableModel and add rows of data using its addRow(Object[]) or addRow(Vector) method. Set this as your JTable's model. The API and the JTable tutorial can get you started.
For e.g.,
ArrayList arrayList = new ArrayList();
String[] columns = {"Field String","Field Double"," Field Double"};
DefaultTableModel model = new DefaultTableModel(columns, 0);
for (Object item : arrayList) {
Object[] row = new Object[3];
//... fill in row with info from item
model.addRow(row);
}
JTable table = new JTable(model);
This demonstrates doing it with a for loop, but a while loop would be similar.