0

I am trying to make a Java JDialog where symbols are displayed in a tableish way. In fact something similar to charmap for windows: enter image description here

But I ran into some issues:

  1. I need the JDialog to be re-sizable so I can't choose to have a table as display, because it needs to be dynamically scaled.(To clarify I mean not just the adjustment of the width of every cell, but the actual amount of the cells in the row/column)

  2. The symbols obviously need to be wrapped in some sort of listener friendly component. But if I choose JButtons, everything looks wrong, because of the different character width in pixel.

  3. Since I have to loop through the symbols to create JButtons I can only make Objects with no name. So how do I even find out which button was pressed?

here is what I've got so far:

Code Updated 05.12.2014

import java.awt.Dimension;

import javax.swing.JDialog;
import javax.swing.JScrollPane;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

import java.awt.FlowLayout;
import java.awt.event.ActionEvent;

import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.border.EmptyBorder;

import java.awt.Color;
import java.awt.GridBagLayout;
import java.awt.GridBagConstraints;
import java.awt.Insets;


public class SymbolDialog extends JDialog{
private char[] math = {8704, 8707, 8708, 8710, 8712, 8713, 8715, 8716, 8721, 8723, 8728, 8730, 8734, 8743, 8744, 8745, 8746, 8747, 8776, 8793, 8800, 8801, 8804, 8805, 8834, 8835, 8836, 8837, 8838, 8839};
private final String[] sTypes = {"Math","Logic", "Arrows"};
private JPanel pan = new JPanel();

public SymbolDialog(){
    try {
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
    } catch (ClassNotFoundException e) {
        System.out.println("catdch 1");
    } catch (InstantiationException e1) {
        System.out.println("catdch 2");
    } catch (IllegalAccessException e1) {
        System.out.println("catdch 3");
    } catch (UnsupportedLookAndFeelException e1) {
        System.out.println("catdch 4");
    }
    SwingUtilities.updateComponentTreeUI(this);

    pan.setPreferredSize(new Dimension(428, 70));
    pan.setLayout(new ColumnsFlowLayout(0,0));
    // Button Build
    for (int i = 0; i < math.length; i++){
        pan.add(new JButton(math[i]+""));
    }  
    GridBagLayout gridBagLayout = new GridBagLayout();
    gridBagLayout.columnWidths = new int[]{0, 0};
    gridBagLayout.rowHeights = new int[]{0, 0, 0};
    gridBagLayout.columnWeights = new double[]{1.0, Double.MIN_VALUE};
    gridBagLayout.rowWeights = new double[]{0.0, 1.0, Double.MIN_VALUE};
    getContentPane().setLayout(gridBagLayout);

    JPanel panel = new JPanel();
    panel.setBorder(new EmptyBorder(5,10,0,10));
    GridBagConstraints gbc_panel = new GridBagConstraints();
    gbc_panel.anchor = GridBagConstraints.WEST;
    gbc_panel.fill = GridBagConstraints.VERTICAL;
    gbc_panel.insets = new Insets(0, 0, 5, 0);
    gbc_panel.gridx = 0;
    gbc_panel.gridy = 0;
    getContentPane().add(panel, gbc_panel);
    GridBagLayout gbl_panel = new GridBagLayout();
    gbl_panel.columnWidths = new int[]{0, 0, 0};
    gbl_panel.rowHeights = new int[]{0, 0};
    gbl_panel.columnWeights = new double[]{1.0, 0.0, Double.MIN_VALUE};
    gbl_panel.rowWeights = new double[]{0.0, Double.MIN_VALUE};
    panel.setLayout(gbl_panel);

    JLabel lblCathegorie = new JLabel("Categories:");
    GridBagConstraints gbc_lblCathegorie = new GridBagConstraints();
    gbc_lblCathegorie.insets = new Insets(0, 0, 0, 5);
    gbc_lblCathegorie.gridx = 0;
    gbc_lblCathegorie.gridy = 0;
    panel.add(lblCathegorie, gbc_lblCathegorie);

    JComboBox<Object> comboBox = new JComboBox<Object>(sTypes);
    GridBagConstraints gbc_comboBox = new GridBagConstraints();
    gbc_comboBox.gridx = 1;
    gbc_comboBox.gridy = 0;
    panel.add(comboBox, gbc_comboBox);

    GridBagConstraints gbc_scrollPane = new GridBagConstraints();
    gbc_scrollPane.fill = GridBagConstraints.BOTH;
    gbc_scrollPane.gridx = 0;
    gbc_scrollPane.gridy = 1;
    getContentPane().add(pan, gbc_scrollPane);

    // Pack
    setDefaultCloseOperation(DISPOSE_ON_CLOSE);
    setResizable(true);
    pack();
    setTitle("Symbols");
    setVisible(true);

}
public void actionPerformed(ActionEvent event) {
    //TODO sysout which symbol was clicked
    System.out.println(((JButton) event.getSource()).getText());
}

public static void main(String[] args){
    new SymbolDialog();
}
}

ps: I use the recommended columns_flow_layout from here

Haeri
  • 621
  • 1
  • 12
  • 27
  • 1
    I would use a JTable to show the chars. – StanislavL Dec 04 '14 at 12:54
  • 1
    I've used a `GridLayout` of `JLabel` with tool tips for this. – trashgod Dec 04 '14 at 12:58
  • @StanislavL But how can I adjust for example the column amount if I would resize the Dialog? – Haeri Dec 04 '14 at 13:00
  • @trashgod can I add an actionListener to a JLabel? – Haeri Dec 04 '14 at 13:00
  • 2
    You can try the http://java-sl.com/tip_columns_flow_layout.html layout with no gaps. It should solve rearrange columns on resizing. – StanislavL Dec 04 '14 at 13:12
  • @dic19 I am really terrible with LayoutManagers.. So how would a GridLayout behave on Dialog resize?? I do like how FlowLayout.Left behaves... – Haeri Dec 04 '14 at 13:12
  • @StanislavL Damn that looked so promising, but that Layout breaks down if you put it into a JScrollPane... :/ – Haeri Dec 04 '14 at 13:20
  • @Haeri you cna try to play with the code changing min/max/pref preferences. Play with public Dimension preferredLayoutSize(Container target) – StanislavL Dec 04 '14 at 13:54
  • 2
    You mean something like in [this question](http://stackoverflow.com/q/18858312/418556)? That uses a `JTable` that resizes according to the size of the frame. – Andrew Thompson Dec 04 '14 at 13:57
  • @AndrewThompson The JTable does infact resize, but not how I was hoping for it to do. I was imagining something more like it is currently doing with the FlowLayout aka. it should automatically add/remove columns/rows.. – Haeri Dec 04 '14 at 14:34
  • @dic19 Ok sorry. Maybe I have to clarify what I mean with "resize": For example if we have 9 symbols and the box has space for 3 items horizontally, then it would layout as 111 \n 111 \n 111. But if we expand the size(resize) the box to have 4 item spaces: 1111 \n 1111 \ 1 should be the result. I am not 100% sure if GridLayout can dynamically adjust column/row amount. – Haeri Dec 04 '14 at 14:41
  • I've removed my comments because now it is clear what do you mean by resizing and those were pointless. The behavior you are looking for pretty much matches with StanislavL's suggestion. @Haeri – dic19 Dec 04 '14 at 14:56
  • @Haeri: _add an `actionListener` to a `JLabel`?_ I didn't; I used a tool tip instead. – trashgod Dec 04 '14 at 20:27
  • Ok I am using the recommended custom flow layout now. But I could still use some help with that action listener... – Haeri Dec 05 '14 at 01:07
  • @Haeri You could always just query the text of the JLabel/JButton to know what symbol was clicked, ((JLabel)e.getSource()).getText(), or if you wanted, you could extend JLabel and add an extra instance variable that stores the character in case this JLabel was going to also display extra data. – NESPowerGlove Dec 05 '14 at 14:21
  • @NESPowerGlove e.getSource() seems just right.. but it wont work for me... I updated the code in OP. Maybe coud could take a look at it? There's really just the listener left and I can implement it into my main application. – Haeri Dec 05 '14 at 14:42
  • @Haeri Well the actionPerformed method isn't going to be called automatically, you have to tell something to call it. That's done by adding an ActionListener to the list of listeners for each button. Any object can be an ActionListener if it's class implements ActionListener. So in this case, you probably want to do 'SymbolDialog extends JDialog implements ActionListener` and `button.addActionListener(this);`. – NESPowerGlove Dec 05 '14 at 15:39

1 Answers1

0

I would use JButton[][] in a GridLayout. For adding them to the JPanel you could use for in a for loop like so:

for(int row = 0; row < ITEMS-PER-ROW; row++){
     for(int col = 0; col < ITEMS-PER-COL; col++){
        JButton[row][col] = new JButton(/*SignToShowAs  String[][]*/)
     }
}
David Maust
  • 8,080
  • 3
  • 32
  • 36