HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavaMinor

Simulating a GUI windowing system

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
systemguiwindowingsimulating

Problem

I was eager to learn the implementation details behind windowing GUI systems. Because I am mostly a high level programmer having not much experience in low-level stuff, I had to simulate it instead of implementing the actual one such as Windows Explorer, KDE, Gnome, X11 and Mac OSX Aqua.

There is the list of things you can do in the simulation:

  • Move the windows by dragging their title bars.



  • Click one to put it on top of other windows.



  • Resize in one direction by dragging a border.



  • Resize in two directions by dragging a corner.



  • Upon resizing, the title will be contracted if does not fit the current width.



MyScreen.java:

```
package net.coderodde.gui.simulation;

import java.awt.Canvas;
import java.awt.Dimension;
import java.util.List;
import java.awt.Toolkit;
import java.util.ArrayList;
import javax.swing.JFrame;

public class MyScreen {

private final static int FRAME_WIDTH = 1024;
private final static int FRAME_HEIGHT = 768;

private final JFrame frame;
private final Canvas canvas;
private final List wndList;
private MyWindow activeWindow;
private MyWindow draggedWindow;
private int draggedWindowOffsetX;
private int draggedWindowOffsetY;
private boolean topBorderLocked;
private boolean rightBorderLocked;
private boolean bottomBorderLocked;
private boolean leftBorderLocked;
private MyWindow highlightedWindow;
private boolean disallowDrag;

public MyScreen() {
wndList = new ArrayList<>();
frame = new JFrame("coderodde GUI simulation");
frame.setSize(FRAME_WIDTH, FRAME_HEIGHT);
frame.setResizable(false);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

final Dimension realScreenDimension =
Toolkit.getDefaultToolkit().getScreenSize();

frame.setLocation((realScreenDimension.width - frame.getWidth()) / 2,
(realScreenDimension.height - frame.getHeight()) / 2);

canvas = new MyCan

Solution

I have some concerns:

public String title() {
    return title;
}

public String title(final String title) {
    final String oldTitle = this.title;
    this.title = title;
    return oldTitle;
}


This looks confusing to me. title() return the title, which is understandable, but title(final String title) returns the old title and sets the title to the argument. What?

I would rename the first methods to getTitle() and the other to getAndChangeTitle(). Also, consider adding setTitle().

This is the same with:

public boolean active() {
    return active;
}

public boolean active(final boolean active) {
    final boolean old = this.active;
    this.active = active;
    return old;
}


Again, active() should be isActive() and active(final boolean active) should be getAndChangeActive().

This is the same with x and y.

I also see some poor naming. For example:

private final List wndList;


What is wndList? A list of wnd? But then what is wnd?

Rename it to something like windowsList or just windows.

Also:

public void addWindow(final MyWindow wnd) {


Again, name wnd to something like window.

public boolean titleBarContainsPoint(final int xx, final int yy) {
    return x() <= xx 
            && xx < x() + width
            && y() <= yy
            && yy < y() + TITLE_BAR_HEIGHT;
}

public boolean windowContainsPoint(final int xx, final int yy) {
    return x() <= xx 
            && xx < x() + width 
            && y() <= yy
            && yy < y() + height;
}

public boolean topBorderContainsPoint(final int xx, final int yy) {
    return x() <= xx && xx < x() + width && (yy == y() || yy == y() + 1);
}

public boolean rightBorderContainsPoint(final int xx, final int yy) {
    return (xx == x() + width - 1 || xx == x() + width - 2) 
            && y() <= yy && yy < y() + height;
}

public boolean bottomBorderContainsPoint(final int xx, final int yy) {
    return x() <= xx 
            && xx < x() + width 
            && (yy == y() + height - 1 || yy == y() + height - 2);
}

public boolean leftBorderContainsPoint(final int xx, final int yy) {
    return (xx == x() || xx == x() + 1) && y() <= yy && yy < y() + height;
}


The whole bunch of methods here all have the names xx and yy. Why can't you just do:

public boolean titleBarContainsPoint(final int x, final int y) {
    return this.x <= x 
            && x < this.x + width
            && this.y <= y
            && y < this.y + TITLE_BAR_HEIGHT;
}

public boolean windowContainsPoint(final int x, final int y) {
    return this.x <= x 
            && x < this.x + width
            && this.y <= y
            && y < this.y + height;
}

public boolean topBorderContainsPoint(final int x, final int y) {
    return this.x <= x && x < this.x + width && (y == this.y || y == this.y + 1);
}

public boolean rightBorderContainsPoint(final int x, final int y) {
    return (x == this.x + width - 1 || x == this.x + width - 2) 
            && this.y <= y && y < this.y + height;
}

public boolean bottomBorderContainsPoint(final int x, final int y) {
    return this.x <= x 
            && x < this.x + width 
            && (y == this.y + height - 1 || y == this.y + height - 2);
}

public boolean leftBorderContainsPoint(final int x, final int y) {
    return (x == this.x || x == this.x + 1) && this.y <= y && y < this.y + height;
}

Code Snippets

public String title() {
    return title;
}

public String title(final String title) {
    final String oldTitle = this.title;
    this.title = title;
    return oldTitle;
}
public boolean active() {
    return active;
}

public boolean active(final boolean active) {
    final boolean old = this.active;
    this.active = active;
    return old;
}
private final List<MyWindow> wndList;
public void addWindow(final MyWindow wnd) {
public boolean titleBarContainsPoint(final int xx, final int yy) {
    return x() <= xx 
            && xx < x() + width
            && y() <= yy
            && yy < y() + TITLE_BAR_HEIGHT;
}

public boolean windowContainsPoint(final int xx, final int yy) {
    return x() <= xx 
            && xx < x() + width 
            && y() <= yy
            && yy < y() + height;
}

public boolean topBorderContainsPoint(final int xx, final int yy) {
    return x() <= xx && xx < x() + width && (yy == y() || yy == y() + 1);
}

public boolean rightBorderContainsPoint(final int xx, final int yy) {
    return (xx == x() + width - 1 || xx == x() + width - 2) 
            && y() <= yy && yy < y() + height;
}

public boolean bottomBorderContainsPoint(final int xx, final int yy) {
    return x() <= xx 
            && xx < x() + width 
            && (yy == y() + height - 1 || yy == y() + height - 2);
}

public boolean leftBorderContainsPoint(final int xx, final int yy) {
    return (xx == x() || xx == x() + 1) && y() <= yy && yy < y() + height;
}

Context

StackExchange Code Review Q#74157, answer score: 4

Revisions (0)

No revisions yet.