Sunday, May 22, 2016

Life as a Game

I like computer games. In the past, I played Starcraft to the point of exhaustion, playing it more than 10 hours at a time for days. The problem with games is that they don't add much to your life. Besides, games are not all fun. Every game I played had a lot of boring repetitive tasks, which resembles real life in that respect.

A good game starts simple and builds up over time whereas in real life I am usually confronted with a large mess. That is what makes games fun and real life a chore. A main reason of procrastination is that I don't know where to start, so I keep postponing it. When I spend some extra time to analyze the problem and divide it into smaller pieces, it becomes manageable, even fun. Writing down what I think helps a lot. And when I solve a problem in real life, I gain skills that I carry with me my whole life, besides having the satisfaction of doing something useful and being able to control my environment.

I still play games (currently Clash of Clans) but I only spend about half an hour a day. I have more fun doing real things (teaching my 4 year old, learning how to make Mousse, developing web apps). I encourage you to view life as a growth opportunity, as a game where every skill you gain unlocks new ones. The key is mentally breaking large chunks of work down into less threatening smaller ones. These small chunks can be dealt with as if they were levels of a larger game.

Inspiration:



Saturday, May 21, 2016

Puana Göre Üniversite Sıralama

İstediğin taban puan aralığını girip üniversitelerin bölümlerini sıralayabileceğin bir web uygulaması oluşturdum, linki şu: http://universite-sorgulama.appspot.com/

Kodu GitHub'a koydum, meraklısı oradan inceleyebilir.

Başkaları tarafından yapılmış daha profesyonel hali: http://universitetercihleri.com/ygs-lys-tercih

Sunday, May 08, 2016

Graphical User Interface Nightmares in Java

Compared to Windows Forms, doing GUI work in Java is painful because you have to deal with a lot more detail. Recently, I was trying to customize tab drawing in JTabbedPane to make the font of the selected tab bold and its background color green. I ended up creating a class (MyTabbedPaneUI) that extends BasicTabbedPaneUI and overrides paintTabBackground().
public class MyFrame extends javax.swing.JFrame {
    public MyFrame() {
        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        javax.swing.JTabbedPane jtp = new javax.swing.JTabbedPane();
        getContentPane().add(jtp);
        jtp.setUI(new MyTabbedPaneUI());
        jtp.add("My Tab 1", new javax.swing.JPanel());
        javax.swing.JLabel jl1 = new javax.swing.JLabel(jtp.getTitleAt(0));
        jtp.setTabComponentAt(0, jl1);
        jtp.add("My Tab 2", new javax.swing.JPanel());
        javax.swing.JLabel jl2 = new javax.swing.JLabel(jtp.getTitleAt(1));
        jtp.setTabComponentAt(1, jl2);
    }
    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                new MyFrame().setVisible(true);
            }
        });
    }
}
public class MyTabbedPaneUI extends javax.swing.plaf.basic.BasicTabbedPaneUI {
    /**
     * NOTE: Do not perform lengthy operations (e.g. setting font to bold) 
     * inside this paint method because it causes high CPU load and has 
     * side effects like not being able to update java3D drawings.
     */    
    @Override
    protected void paintTabBackground(Graphics g, int tabPlacement, 
                       int tabIndex, int x, int y, int w, int h, 
                       boolean isSelected) {
        for (int i = 0; i < tabPane.getTabCount(); i++) {
            Color bgColor = Color.YELLOW;
            javax.swing.JLabel jl = (javax.swing.JLabel) 
                tabPane.getTabComponentAt(i);
            if (jl != null) {
                if (i != tabIndex) {
                    bgColor = Color.GREEN;
                    //jl.setFont(jl.getFont().deriveFont(Font.PLAIN));//BAD
                } else {
                    //jl.setFont(jl.getFont().deriveFont(Font.BOLD));//BAD
                }
            }
            Rectangle rect = rects[i];
            int pad = 2;
            g.setColor(bgColor);
            g.fillRect(rect.x+pad, rect.y+pad, rect.width-2*pad,
                rect.height-2*pad);
        }
    }
}
Setting font to bold (by uncommenting the lines commented as "BAD") in BasicTabbedPaneUI.paintTabBackground causes more than 7x CPU usage:


I have witnessed cases where CPU usage shot up to 100% and my app could not update a java3D drawing on another window. You can imagine that it was not easy to find out why.

Other examples of why Java should be avoided for GUI work:
  • Changing color of a JTable cell is a lot of work.
  • For background color to have any effect, JLabel has to be opaque while JTextArea has to be not opaque (opposite of their defaults)!
  • Due to the unintuitive layout mechanism, what I see on design view is completely different from what I see when I run the application.
  • When I change the layout, sometimes all the components dissappear (their width and height becomes zero).
  • Setting the width/height to "Preferred" sometimes causes the component to shrink to zero size. From what I understand, the layout mechanism is there to ensure proper resizing, i.e. to have a similar look when screen resolutions, font size etc. change. As usual, when trying the solve the most general case, you make it more difficult to solve simple cases.
  • To properly set size of a JFrame or JDialog, calling setPrefferedSize() is not enough, you have to call pack() afterwards.
  • When, in design mode, you rearrange buttons, labels or when you just change the border of panels, NetBeans might convert them to local variables and you have to manually convert them back to private to be able to reference them.
  • 10.04.2019: If you have rows of panels and want to use a JPanel instead of JTable to house subpanels, you have to call JPanel.setPreferredSize() and then revalidate() / repaint() for JScrollPane to update itself. JTable complicates matters due to it's editor / renderer mechanism, so use JPanel whenever you have a panel inside a table.
  • 10.04.2019: If you have a JFormattedTextField with latitude format in it, you might need to call JFormattedTextField.commit() when you edit the text and want degree sign to remain in field.
My layout strategy:
  • Create a frame
  • Add a panel with null layout.
  • Add subpanels to group components
  • Set the layout of subpanels. The layouts I use most often:
    • null
      • Advantage: You can set the location and size of components.
      • Disadvantage: If your form is resizable, components won't resize.
    • GridLayout;
    • BoxLayout
  • With null layout, to set location and size, use setBounds() instead of setPreferredSize().