What does a good GUI toolkit need?

Accname

2D-Graphics enthusiast
Reaction score
1,462
Hi guys.

I am toying around about writing my own GUI toolkit right now. Its quite fun and I enjoy it a lot up to this point. But then I realize, I actually dont know that much about many good GUI toolkits out there; I have hardly worked with more then 3 or so.

So I am going to ask all of you, what do you think a GUI toolkit really needs. What are the most important features? (besides displaying a GUI, duh!)
 

s3rius

Linux is only free if your time is worthless.
Reaction score
130
What kind of GUI? Similar to the Windows GUI, with buttons and text labels and everything?
 

Accname

2D-Graphics enthusiast
Reaction score
1,462
Yeah. Like swing, AWT, Qt, etc.

I just love building that shit. Right now I have basic buttons, checkboxes, labels, textboxes, textareas, pane's and panels, and simple layouts like border layout, flow layout, etc.
But that is not the complicated stuff. I wanna know what kind of great functionality a GUI toolkit should bring. What is really needed, what is outdated, what would be new and exiting, etc.
I just love to toy around with the code a little and see what happens.
 

monoVertex

I'm back!
Reaction score
460
I don't have experience with many GUI toolkits, I just have one thing to say: don't do anything remotely close to how Java FX does it, please :(.
 

Accname

2D-Graphics enthusiast
Reaction score
1,462
How does java FX do it? Never worked with that.
Can you give me a quick example of what you dislike about it?
 

monoVertex

I'm back!
Reaction score
460
Uh, I'll write a more detailed post later, I'm currently studying for a final. I also have to go a bit over my code, as I only used it for some assignments and don't remember stuff right away. The best example is how they handle tables with data, I'll focus on that, it's the ugliest thing I've ever seen.
 

s3rius

Linux is only free if your time is worthless.
Reaction score
130
Drag&Drop support maybe? TileViews with icons and/or labels as list elements. Sliders. Some basic animations for buttons if you don't have already (hover/depress/normal states). Fade in/out animations for all kinds of UI elements.
 

Accname

2D-Graphics enthusiast
Reaction score
1,462
Do other GUI's not have sliders? They are quite simple actually.

Drag&Drop and Fade-in / Fade-out might be interesting. I have to think about it.

How do you think a standard Drag&Drop should work? Maybe have an interface "Dragable" and "DragableContainer" and a Dragable can be dragged and dropped into a DragableContainer. How's that?

Something like this:
Code:
interface DragableContainer

Dragable getTouchedDragable(); // when the mouse has clicked a dragable inside this container
boolean canDrag(Dragable d); // true when the dragable can be dragged from this container
boolean canDrop(Dragable d);
void drag(Dragable d);
void drop(Dragable d);
Code:
interface Dragable

boolean canDrag();
boolean canDrop();
void updateDrag();
void onDrag();
void onDrop();
Or what are your suggestions?
 

s3rius

Linux is only free if your time is worthless.
Reaction score
130
Do other GUI's not have sliders? They are quite simple actually.

I was just suggesting things that are interesting or useful for a nice GUI. And sliders are pretty neat.

Regarding D&D - it depends on what you understand as D&D. I actually thought about being able to drag files from the explorer into the GUI (or certain compotents of it), like it's possible with many applications (e.g. dragging a txt file into Notepad++ would open it).

Regarding your idea:
I'd move the active part entirely into the Dragable interface.

Code:
interface Dragable

void canBeDragged(); //might want to enable/disable dragging for indiv components
void updateDrag();
void onDrag(); //Start of movement
void onDrop(DropableContainer newParent); //End of movement, removes itself from old parent, adds itself to new paren, fails if newParent cannot receive any more components
 

Varine

And as the moon rises, we shall prepare for war
Reaction score
803
Can I ask what it's for? Like are you working on just some kind of general framework, or do you have a specific endgame for it?
 

Accname

2D-Graphics enthusiast
Reaction score
1,462
Can I ask what it's for? Like are you working on just some kind of general framework, or do you have a specific endgame for it?
Nothing really; I just like toying around with many thousand lines of code and build complex systems for the heck of it.

@s3rius:
Might work too. But then I would have to make sure each Dragable implements those methods correctly. When I give users the ability to create their own dragable classes I would prefer it, if they can not do anything wrong because they are too inexperienced. So I would rather put the majority of the code into the dragableContainer classes because they are less likely to be customized.
 

monoVertex

I'm back!
Reaction score
460
Ok, so basically, in order to create and properly populate a table in JavaFX, you have to do this:

Code:
    public class TableRow {
        private User user;

        private TableRow(User user) {
            this.user = user;
        }

        public Object getFirstName() {
            return user.get("first_name");
        }

        public Object getLastName() {
            return user.get("last_name");
        }

        public User getUser() {
            return user;
        }
    }

    private TableView<TableRow> resultsTable;

[...]

        // Create the columns for the search results table.
        TableColumn<TableRow, Object> column;

        for (String[] columnText : Constants.USER_SEARCH_INFORMATION) {
            column = new TableColumn<TableRow, Object>(columnText[0]);
            column.setCellValueFactory(new PropertyValueFactory<TableRow, Object>(columnText[1]));

            resultsTable.getColumns().add(column);
        }

        resultsTable.setItems(resultsData);

Obviously I stripped out some lines, but you should get the idea. You have to create a special class that defines the row of a table. This is really awful because you cannot have content-dependent tables at run-time. Say, if I want to have 2 tables with only one column different depending on some state, I'd need 2 separate classes. Of course, they could extend a parent Row class, but that is still overkill, in my opinion. It would be better to be able to somewhat register / de-register columns, or something along those lines, on run-time. This kind of fixed design is not really good.

Another thing that is really bad with this design is that it's extremely hard and cumbersome to access a cell or a row, to assign some handles on that, say a click or a hover. Row is somewhat easier, but for cell access, you have to override the default Cell Factory the table uses, which results in a ton of extra code.

Something else that bothered me during developing with Java FX is that when assigning handlers for various events, you have to assign some object which extends an interface. It would be easier if I could specify a callback method instead, so I can group handlers for a View in a single object, for example. However, I'm not sure how much you can do this in Java (I'm assuming you're writing this stuff in Java).

One thing that I liked with JavaFX is that you can use FXML files to describe your GUI view instead of creating it procedurally. This is better for maintenance and markup languages are in general better at describing GUI elements than other languages (after all this is their purpose). Now, if the toolkit was something sane and easy to use, then something like this is not really not necessary, but you can always keep this in mind.

Using such a mechanism also allows for a GUI builder to be used, something in which you can visualize the result and which spits the XML for you.
 

Accname

2D-Graphics enthusiast
Reaction score
1,462
If I had to give an example of how I would try to implement a Table interface, I guess I would go with this:
Code:
public interface Table {
    public void setSize(int columns, int rows);
    public void insertColumn(int columnID); // inserts a new empty column in before the column at columnID
    public int getColumnCount();
    public void insertRow(int rowID); // inserts a new empty row in before the row at rowID
    public int getRowCount();
    public void setAt(int column, int row, Object content);
    public Object getAt(int column, int row);
    public Object[] getColumn(int columnID);
    public Object[] getRow(int rowID);
    public Object[][] getCells(int fromColumn, int toColumn, int fromRow, int toRow);
}
when using the table it would look like this:
Code:
    public void createTable() {
        Table table = new Table();
        table.setSize(1, 5); // create table with 1 colum and 5 rows
        table.setAt(0, 0, 5); // at the first cell (from top) we put the number 5
        table.setAt(0, 1, "Test"); // second cell (from top) we put the String "Test"
        table.setAt(0, 2, null); // the third cell is simply left empty; setting to null can be omitted in this example since its already null
        table.setAt(0, 3, 3.6);
        table.setAt(0, 4, new Rect(0, 5, 13, 6)); // uses the objects toString() method to fill the cell with data
        table.getAt(0, 3); // returns 3.6
    }


When talking about callbacks I must tell you that I really dont like them. I will go with the standard java listener approach. You could use reflection with java to do stuff like in Qt; but that really messes up modern IDE's and makes debugging a real pain.

And XML files... I dont know. I actually dont like to force users to use other external files to use the functionality of the classes. I will simply give the user a powerful interface to work with, and when the user wants to use XML files for that they can always write their own parser or use some other XML reader for the task.

But thank you for the input.
 

monoVertex

I'm back!
Reaction score
460
If I had to give an example of how I would try to implement a Table interface, I guess I would go with this:
Code:
public interface Table {
    public void setSize(int columns, int rows);
    public void insertColumn(int columnID); // inserts a new empty column in before the column at columnID
    public int getColumnCount();
    public void insertRow(int rowID); // inserts a new empty row in before the row at rowID
    public int getRowCount();
    public void setAt(int column, int row, Object content);
    public Object getAt(int column, int row);
    public Object[] getColumn(int columnID);
    public Object[] getRow(int rowID);
    public Object[][] getCells(int fromColumn, int toColumn, int fromRow, int toRow);
}
when using the table it would look like this:
Code:
    public void createTable() {
        Table table = new Table();
        table.setSize(1, 5); // create table with 1 colum and 5 rows
        table.setAt(0, 0, 5); // at the first cell (from top) we put the number 5
        table.setAt(0, 1, "Test"); // second cell (from top) we put the String "Test"
        table.setAt(0, 2, null); // the third cell is simply left empty; setting to null can be omitted in this example since its already null
        table.setAt(0, 3, 3.6);
        table.setAt(0, 4, new Rect(0, 5, 13, 6)); // uses the objects toString() method to fill the cell with data
        table.getAt(0, 3); // returns 3.6
    }

This looks like what I had in mind, so that's cool. It gives more control to the user, which is what's missing in JavaFX.

When talking about callbacks I must tell you that I really dont like them. I will go with the standard java listener approach. You could use reflection with java to do stuff like in Qt; but that really messes up modern IDE's and makes debugging a real pain.

Well, I worked with and like JavaScript a lot (and other functional languages), where you pass callbacks like there's no tomorrow, so I may be a little biased on this :D.

And XML files... I dont know. I actually dont like to force users to use other external files to use the functionality of the classes. I will simply give the user a powerful interface to work with, and when the user wants to use XML files for that they can always write their own parser or use some other XML reader for the task.

But thank you for the input.

What I meant was an alternative, not force the users to do it the XML way. JavaFX has exactly that: you can either use the classes and do everything in the code or use the JavaFX's FXML loader and instantiate your view class with most of the GUI already loaded (and you can modify it some more in the code, if needed).

However, I realize this is more complicated and not of so much importance, so I suggested it as a feature for late-development, after you already wrote most of the toolkit.
 
General chit-chat
Help Users
  • No one is chatting at the moment.

      The Helper Discord

      Staff online

      Members online

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top