Showing posts with label Java. Show all posts
Showing posts with label Java. Show all posts

2014-01-12

Netbeans Portable JDKHOME

You may get this dialog message when starting Netbeans Portable: Cannot find java.exe in specified jdkhome.. For me, the dialog appears because I have a JDK installed instead of inside the Netbeans Portable folder. To avoid responding to this message every time I start Netbeans, I made two changes to my configuration files:

?
  1. Close Netbeans first. If you don't close Netbeans, it will overwrite your changes to the configuration files.
  2. Edit ...\NetBeans_JavaSE_7.4_Portable\App\netbeans\etc\netbeans.conf and set netbeans_jdkhome to the path of your JDK installation.
  3. Edit ...\NetBeans_JavaSE_7.4_Portable\App\AppInfo\Launcher\NetBeansPortable.ini and comment out the section that overwrites netbeans_jdkhome. You comment out lines in an INI file by inserting a semicolon in the first column of a row.

2011-11-26

Minimal JavaBean introspection example

Just playing with JavaBeans, so here's a small example to create a simple JavaBean, set a property and read it.

import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class SimpleBean {

  private final String name = "SimpleBean";
  private int size;
  public int getSize() {
    return size;
  }
  public void setSize(int size) {
    this.size = size;
  }
  public String getName() {
    return name;
  }
  
  public static void main(String[] args) throws IntrospectionException {
    SimpleBean sb = new SimpleBean();
    sb.setSize(59);
    BeanInfo bi = Introspector.getBeanInfo(sb.getClass());
    for (PropertyDescriptor pd : bi.getPropertyDescriptors()) {
      testGetValue(sb, pd);
    }
  }
  
  public static void testGetValue(Object sb, PropertyDescriptor pd) {
    System.out.print(pd.getName() + "=");
    Method getter = pd.getReadMethod();
    Object arg1[] = {};
    try {
      Object value = getter.invoke(sb, arg1);
      System.out.println(value);
    } catch (IllegalArgumentException e) {
      e.printStackTrace();
    } catch (IllegalAccessException e) {
      e.printStackTrace();
    } catch (InvocationTargetException e) {
      e.printStackTrace();
    }
  }
}

The output of the program is:

class=class SimpleBean
name=SimpleBean
size=59

2008-11-08

Simple Clock Custom Control using Swing and Windows.Forms

This article describes how to create a simple analogue clock using Java Swing and .Net Windows.Forms, and it will cover creating a custom control, simple 2D drawing, updating the display regularly with a timer. In addition, the control can display the time in a user-selectable time zone and is resizable.

To give you an idea of the goal, below are images of the Swing and Windows.Forms control, respectively, in a test application:

Clock Control Java Clock Control .Net

Define Custom Control

The custom control has to draw a clock face and hands. We specify the height and width of the clock face and use a high-quality drawing mode to smooth out the lines and avoid jaggies. By default, the control will display the time in the current time zone.

Java Swing

Sub-class JComponent and override the paintComponent() method:

public class ClockPanel extends JPanel {
  private double cx, cy, diameter, radius;
  private final double RADIAN = 180.0 / Math.PI;
  private TimeZone timeZone = null;

  public void paintComponent(Graphics g) {
    super.paintComponent(g);
    Graphics2D g2 = (Graphics2D) g;
    g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    paintFace(g2);
    paintHands(g2);
  }
}

Windows.Forms

Sub-class Control and override OnPaint() method:

  public partial class ClockControl : Control {
    private double cx, cy, diameter, radius;
    private const double RADIAN = 180.0 / Math.PI;
    private TimeZoneInfo tzi = TimeZoneInfo.Local;

    protected override void OnPaint(PaintEventArgs e) {
      base.OnPaint(e);
      Graphics g = e.Graphics;
      g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
      PaintFace(g);
      PaintHands(g);
    }
  }

2D Drawing

The clock is drawn in two steps: first a circular clock face is drawn, then the hands are drawn on top of the face. The face is circular, so the minimum of the height and width of the drawable area is used.

Clock Face

To drawing the clock face's numbers, we convert each number into string, then an image, compute that image's mid-point and place it numbers using that mid-point. If we don't use the mid-point, then each number will be placed too high and on the right of the tip of the clock hands.

Java Swing
  private void paintFace(Graphics2D g2) {
    g2.setPaint(Color.GRAY);
    g2.fill(new Ellipse2D.Double(0, 0, diameter, diameter));
    g2.setPaint(Color.LIGHT_GRAY);
    g2.fill(new Ellipse2D.Double(20, 20, diameter - 40, diameter - 40));
    g2.setPaint(Color.BLACK);
    for (int i = 1; i <= 12; i++) {
      TextLayout tl = new TextLayout(Integer.toString(i), getFont(), g2.getFontRenderContext());
      Rectangle2D bb = tl.getBounds();
      double angle = (i * 30 - 90) / RADIAN;
      double x = (radius - 10) * Math.cos(angle) - bb.getCenterX() / 2;
      double y = (radius - 10) * Math.sin(angle) - bb.getCenterY() / 2;
      tl.draw(g2, (float)(cx + x), (float)(cy + y));
    }
  }
Windows.Forms
    private void PaintFace(Graphics g) {
      SolidBrush brush = new SolidBrush(Color.DarkGray);
      g.FillEllipse(brush, 0, 0, (float)diameter, (float)diameter);
      brush.Color = Color.LightGray;
      g.FillEllipse(brush, 20, 20, (float)(diameter - 40), (float)(diameter - 40));
      brush.Color = Color.Black;
      for (int i = 1; i <= 12; i++) {
        string num = Convert.ToString(i);
        Size size = TextRenderer.MeasureText(g, num, Font, new Size(int.MaxValue, int.MaxValue), TextFormatFlags.NoPadding);
        double angle = (i * 30 - 90) / RADIAN;
        double x = (radius - 10) * Math.Cos(angle) - size.Width/2;
        double y = (radius - 10) * Math.Sin(angle) - size.Height/2;
        g.DrawString(num, Font, brush, (float)(cx+x), (float)(cy+y));
      }
      brush.Dispose();
    }

Calculate Hand Positions

For each tick, we calculate the position of the hour, minute and second hands based on the current time and time zone. The hour hand is moved slightly forward each minute, and the minute hand is moved slightly forward each second, so that they don't jump at the start of the next hour and minute, respectively.

Java Swing
  private void paintHands(Graphics2D g2) {
    Calendar now = Calendar.getInstance(timeZone);
    int hour = now.get(Calendar.HOUR_OF_DAY);
    int minute = now.get(Calendar.MINUTE);
    int second = now.get(Calendar.SECOND);
    double angle = 0.0;
    
    angle = (hour % 12 * 30 + minute / 2) / RADIAN;
    paintHand(g2, 0.4, angle, 6, Color.YELLOW);
    
    angle = (minute * 6 + second / 10) / RADIAN;
    paintHand(g2, 0.6, angle, 4, Color.BLUE);
    
    angle = second * 6 / RADIAN;
    paintHand(g2, 0.8, angle, 2, Color.RED);
  }
Windows.Forms
    private void PaintHands(Graphics g) {
      DateTime dt = DateTime.UtcNow + tzi.GetUtcOffset(DateTimeOffset.UtcNow);
      double angle = 0.0;

      angle = (dt.Hour % 12 * 30 + dt.Minute / 2) / RADIAN;
      PaintHand(g, 0.4, angle, 6f, Color.Yellow);

      angle = (dt.Minute * 6 + dt.Second / 10) / RADIAN;
      PaintHand(g, 0.6, angle, 4f, Color.Blue);

      angle = dt.Second * 6 / RADIAN;
      PaintHand(g, 0.8, angle, 2f, Color.Red);
    }

Draw Hands

Now, we draw each clock hand.

Java Swing
  private void paintHand(Graphics2D g2, double proportion, double angle, float width, Color color) {
    double x = radius * proportion * Math.sin(angle);
    double y = -radius * proportion * Math.cos(angle);
    g2.setPaint(color);
    g2.setStroke(new BasicStroke(width, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
    g2.draw(new Line2D.Double(cx, cy, cx + x, cy + y));
  }
Windows.Forms
    private void PaintHand(Graphics g, double proportion, double angle, float width, Color color) {
      double x = radius * proportion * Math.Sin(angle);
      double y = -radius * proportion * Math.Cos(angle);
      Pen pen = new Pen(color, width);
      pen.EndCap = System.Drawing.Drawing2D.LineCap.Round;
      g.DrawLine(pen, (float)cx, (float)cy, (float)(cx + x), (float)(cy + y));
      pen.Dispose();
    }

Timer

The clock control updates itself every second using a timer. We set up the timer in the control's constructor.

Java Swing

Each 1000 ms, the timer will add a repaint request to the Swing event queue, which eventually results in calling the object's paintComponent() method.

  public ClockPanel() {
    super();
    ...  
    setTimeZone(TimeZone.getDefault());
    Timer t = new Timer(1000, new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        repaint();
      }
    });
    t.start();
  }

Windows.Forms

Each 1000 ms, the timer will call the timer_Tick() function, which in turn invalidates the clock control so that Windows.Forms will generate a OnPaint() event (that's how I think it works).

    public ClockControl() {
      CalculateSize(); // Control's size is available at this point.
      Timer timer = new System.Windows.Forms.Timer();
      timer.Enabled = true;
      timer.Interval = 1000;
      timer.Tick += new EventHandler(timer_Tick);
    }

    void timer_Tick(object sender, EventArgs e) {
      Invalidate();
    }

Time Zones

For interest, the clock control displays the time is a specified time zone, so we provide methods for an external caller to get and set the control's time zone.

Java Swing

  public TimeZone getTimeZone() { return timeZone; }
  public void setTimeZone(TimeZone tz) { timeZone = tz; }

Windows.Forms

    public TimeZoneInfo TZI {
      get { return tzi; }
      set { tzi = value; }
    }

Test Code

To test the clock control, create a test application.

NetBeans

  1. Using NetBeans, create a new application sample form called SimpleClockView.
  2. Drag the clock's source code icon from the Projects window into SimpleClockView's Design pane.
  3. Drag a JComboBox, called timeZoneList into the Design pane.
  4. Add the following action handler into timeZoneList to change the clock's time zone when the user selects a new time zone:
      private void timeZoneListActionPerformed(java.awt.event.ActionEvent evt) {
        // TODO add your handling code here:
        String tzID = (String) this.timeZoneList.getSelectedItem();
        clockPanel1.setTimeZone(TimeZone.getTimeZone(tzID));
      }                                            
    
  5. Initialize timeZoneList with a list of time zones in SimpleClockView's constructor:
    public class SimpleClockView extends FrameView {
    
        public SimpleClockView(SingleFrameApplication app) {
            super(app);
    
            initComponents();
            String[] sortedTzID = TimeZone.getAvailableIDs();
            Arrays.sort(sortedTzID);
            timeZoneList.setModel(new javax.swing.DefaultComboBoxModel(sortedTzID));
        ...
    

SharpDevelop

  1. Using SharpDevelop, create a new Windows Applications Form called Form1.
  2. Drag your new clock control from the Toolbox into the Form1's Designer pane.
  3. Drag a ListBox, called timeZoneList into the Design pane.
  4. Bind timeZoneList's SelectedIndexChange event to the timeZoneList_SelectedIndexChange() function to change the clock's time zone when the user selects a new time zone:
        private void timeZoneList_SelectedIndexChanged(object sender, EventArgs e) {
          String tzId = this.timeZoneList.SelectedValue as String;
          if (tzId != null) this.clockControl1.TZI = TimeZoneInfo.FindSystemTimeZoneById(tzId);
        }
    
  5. Initialize timeZoneList with a list of time zones in Form1's constructor:
    namespace ClockNS {
      public partial class Form1 : Form {
        public Form1() {
          InitializeComponent();
          this.timeZoneList.DataSource = TimeZoneInfo.GetSystemTimeZones();
          this.timeZoneList.DisplayMember = "DisplayName";
          this.timeZoneList.SelectedValue = "Id";
        }
      ...
      }
    }
    

Handling Resizing

A nice additional feature is for the clock control to resize itself when the test application's is resized.

Java Swing

Add a componentResized handler to recalculate the component's size and request Swing to repaint the component. Your component may have a small inset within its boundary, so you should take that into account when calculating the clock's size.

  public ClockPanel() {
    super();
  
    addComponentListener(new ComponentAdapter() {
      @Override
      public void componentResized(ComponentEvent e) {
        calculateSize();
        repaint();
      }
    });
    ...
  }

  private void calculateSize() {
    Insets insets = getInsets();
    int width = getWidth() - insets.left - insets.right;
    int height = getHeight() - insets.top - insets.bottom;
    diameter = Math.min(width, height);
    cx = cy = radius = diameter / 2;
  }

Windows.Forms

Override the base class' OnResize() function to recalculate the clock's size and redraw the control.

    protected override void OnResize(EventArgs e) {
      base.OnResize(e);
      CalculateSize();
      Invalidate();
    }

    private void CalculateSize() {
      diameter = Math.Min(this.Width, this.Height) - 2;
      cx = cy = radius = diameter / 2;
    }

Conclusion

I've described how to create a custom control in Java Swing + NetBeans and .Net Windows.Forms + SharpDevelop using (nearly) the same procedure and structure. I experiment with both environments because a feature in one motivates me to find an equivalent feature in the other and to synthesize a common (and hopefully better) solution.

See Also

2008-09-13

NetBeans JUnit "Forked Java VM exited abnormally"

While trying to run a test case for a Java program in NetBeans using JUnit, my test suite failed and I found this error:

Forked Java VM exited abnormally. Please note the time in the report does not reflect the time until the VM exit.
junit.framework.AssertionFailedError
at org.netbeans.core.execution.RunClassThread.run(RunClassThread.java:151)

For some reason, NetBeans could not start a new virtual machine (I guess that's what the 'fork' means). I used NetBeans to debug the Ant test target and found in the nbproject\build-impl.xml file …

    <target name="-init-macrodef-junit">
        <macrodef name="junit" uri="http://www.netbeans.org/ns/j2se-project/3">
            <attribute default="${includes}" name="includes"/>
            <attribute default="${excludes}" name="excludes"/>
            <attribute default="**" name="testincludes"/>
            <sequential>
                <junit dir="${work.dir}" errorproperty="tests.failed" failureproperty="tests.failed" fork="true" showoutput="true">
…

replacing fork="true" with fork="false" gave a more meaningful error message:

Exit from within execution engine, normal
org.netbeans.core.execution.ExitSecurityException: Exit from within execution engine, normal
…
        at org.netbeans.core.execution.SecMan.checkExit(SecMan.java:66)
        at org.netbeans.TopSecurityManager.checkExit(TopSecurityManager.java:145)
        at java.lang.Runtime.exit(Runtime.java:88)
        at java.lang.System.exit(System.java:906)
        at PrintLineNumber.Main.main(Main.java:16)
        at PrintLineNumber.MainTest.testMainNoArguments(MainTest.java:47)
        at org.netbeans.core.execution.RunClassThread.run(RunClassThread.java:151)

So, the NetBeans security manager does not allow my program to call System.exit(1), which is fair enough, otherwise (I guess) NetBeans would exit as well.

The location of the problem is in the test code below, created by NetBeans, which calls the main() method of my application:

44  public void testMain() {
45    System.out.println("main");
46    String[] args = null;
47    Main.main(args);
48  }

And here is the code that was tripping JUnit:

15      if (args == null || args.length != 2) {
16        System.exit(1);
17      }

My code was checking if the argument list is null, but that should never happen in normal use because the Java launcher always calls main() with a String array, not null. I removed the test for a null args and allowed a NullPointerException to be thrown. Then I added a test case for this situation:

  @Test(expected=NullPointerException.class)
  public void testMainNullArguments() {
    Main.main(null);
  }

Now, JUnit runs my test suite to completion!

2008-08-27

What's the time?

14 quick ways to find the current time on your computer.

Cmd.exe has two built-in commands for the date and time. You have to add the /t option when calling these commands otherwise you are prompted to set the system time:

> date /t
Wed 27/08/2008
> time /t
07:42 PM

GnuWin's date command prints the date, time and time zone:

> date
Wed Aug 27 19:43:23 AUS Eastern Standard Time 2008

You can use the POSIX module in Perl to get the current date and time:

> perl -e "use POSIX; print asctime(localtime());"
Wed Aug 27 19:44:21 2008

Python has a time module similar to Perl's:

> python -c "import time; print time.asctime()"
Wed Aug 27 19:48:07 2008

PHP's time and date functions return an array, which you can dump using the print_r() function:

> php -r "print_r(get_date());"
Array
(
    [seconds] => 49
    [minutes] => 34
    [hours] => 14
    [mday] => 30
    [wday] => 6
    [mon] => 8
    [year] => 2008
    [yday] => 242
    [weekday] => Saturday
    [month] => August
    [0] => 1220070889
)

Ruby has a Time class:

> ruby -e "print Time.now"
Wed Aug 27 19:45:32 +1000 2008

PowerShell has a get-date cmdlet:

> get-date
Wednesday, 27 August 2008 7:50:13 PM

Or use the .Net System.DateTime.Now property in PowerShell:

> [System.DateTime]::Now
Thursday, 28 August 2008 9:53:21 AM

Firefox can tell you the time using the Javascript Date() object. Enter the following statement in your browser's address bar:

javascript:Date()
Wed Aug 27 2008 20:11:27 GMT+1000 (AUS Eastern Standard Time)

MSIE6 has a similar object but the output is different from Firefox's:

javascript:Date()
Thu Aug 28 10:06:59 2008

Groovy (and Java) has a java.util.Date object which defaults to the current time:

new java.util.Date()
Result: Thu Aug 28 09:58:45 EST 2008

2008-01-06

Four Function Calculator using Java and Swing

Finished a longish article, with sample source code, about writing a simple desktop application in Java and Swing. It discusses model-view-controller, Java resource bundles and Swing AbstractAction.

This blog entry is used for discussion, if any.

2007-12-15

Two Hello World Windows in Groovy

Groovy is scripting language on the Java platform. Groovy is interesting because it can be compiled into Java byte-code and makes heavy use of closures.

Groovy Hello World

In the beginning, I ported my Jython version into Groovy. It looks pretty much the same as the Jython version:

// Hello World in Groovy
f = new javax.swing.JFrame("Hello World")
f.setSize(170,70)
f.contentPane.layout = new java.awt.FlowLayout()
f.defaultCloseOperation = javax.swing.JFrame.EXIT_ON_CLOSE
f.add(new javax.swing.JLabel("Label me:"))
f.add(new javax.swing.JButton("Press me"))
f.show()

Groovy + SwingBuilder Hello World

Groovy has a helper class called SwingBuilder to make it much easier to write Swing applications. Here's one way to re-write the program:

// Hello World Window in Groovy + SwingBuilder
sb = new groovy.swing.SwingBuilder()
f = sb.frame(
  title:"Hello World"
  ,size:[170,70]
  ,defaultCloseOperation: javax.swing.JFrame.EXIT_ON_CLOSE) {
  flowLayout()
  label(text:"Label me:")
  button(text:"Press me")
}
f.show()

SwingBuilder is quite wonderful because it allows you to define a GUI with a minimum of code noise. The definition of a JFrame probably maps a keyword X to a setX() function but I haven't worked out how SwingBuilder converts words such as flowLayout(), label and button to Swing objects and functions.

2007-12-14

IronPython and Jython Hello Windows

The Python language has been ported to two major virtual machine platforms: IronPython for Microsoft .Net and Jython for Java. To get a flavour of these implementations, here are two Hello World scripts that open a window containing a label and a button.

IronPython Hello World Window

import clr
clr.AddReference("System.Drawing")
from System.Drawing import ContentAlignment, Size
clr.AddReference("System.Windows.Forms")
from System.Windows.Forms import Button, FlowLayoutPanel, Form, Label

p = FlowLayoutPanel()
p.Controls.Add(Label(Text="A label:", Size=Size(50,20), TextAlign=ContentAlignment.BottomLeft))
p.Controls.Add(Button(Text="Press Me"))
f = Form(Text="Hello World", Size=Size(160,70))
f.Controls.Add(p)
f.ShowDialog()

Jython Hello World Window

# Jython Hello Window
from java.awt import FlowLayout
from javax.swing import JButton, JFrame, JLabel

f = JFrame("Hello", defaultCloseOperation=JFrame.DISPOSE_ON_CLOSE, size=(170,70), layout=FlowLayout())
f.add(JLabel("A label:"))
f.add(JButton("Press Me"))
f.show()

Mini Observations

  • IronPython makes loading the .Net libraries explicit by using the clr module.
  • Both implementations allow setX functions in object constructor's argument list.

2007-11-12

Weird NLS_LANG JDBC Connection Error

A colleague got a new computer and when he tried to connect to an Oracle server with a JDBC client, he got this error:

ORA-12705: Cannot access NLS data files or invalid environment specified

After comparing our Java environments, he found that he had user.country = BZ (BZ is the top level domain for Belize). He changed his Regional and Language Options to English (Australia) and then he had no problems connecting to the Oracle server.

I think when JDBC client tries to connect to the Oracle server, the client specifies its locale and when the Oracle server fails to find the required locale files, the server throws the ORA-12705 error message.

2007-04-29

JDBC to SQL Server Express

Connecting JDBC-based tools such as SQL Developer or DbVisualizer to SQL Server Express required the following steps:

  • Obtain JDBC Driver
  • TCP/IP for SQL Server Express
  • Authentication Method

Obtain JDBC Driver

Using SQL Developer, when you get the following exception …

Unable to find driver: net.sourceforge.jtds.jdbc.Driver

… download the jTDS JDBC driver and install it in your JRE's ext folder. The latest version of the driver is 1.2. Of course, there are other JDBC drivers for SQL Server you can use.

TCP/IP for SQL Server Express

By default, TCP/IP for SQL Server Express is disabled, so JDBC cannot connect to it and you may get the following exception …

Network error IOException: Connection refused: connect

Enable TCP/IP

To enable TCP/IP, start SQL Server Configuration Manager.

  1. Expand SQL Server 2005 Network Configuration node.
  2. In the right pane, select Protocols for SQLEXPRESS. The right pane should now show Protocols and Status columns.
  3. Select Enable from the TCP/IP context menu.

Find or Configure TCP/IP Port

After enabling TCP/IP, you have to find out which port number to use. SQL Server Express allocates a port dynamically each time it is started, so to find or configure the port number, continue using SQL Server Configuration Manager

  1. Select Properties from the TCP/IP context menu. The TCP/IP Properties dialog should open.
  2. Select the IP Addresses tab.
  3. In the IPAll node …
    1. The TCP Dynamic Ports field shows the currently used port number. If you set that field to blank, then SQL Server Express should not automatically choose another port when it restarts.
    2. Set the desired port number in the TCP Port field.
    3. Press OK to apply your settings and close the dialog.

Test TCP/IP

If you change the TCP/IP port, you have to restart SQL Server Express before it can use the new port number. To test that your port number is used, start a cmd window and type: netstat -an. For instance, if you used port 1433, you should see this line in the list of ports used:

TCP    0.0.0.0:1433           0.0.0.0:0              LISTENING

Authentication Method

By default, SQL Server Express uses Windows Authentication Mode to authenticate connections. If you get this exception …

Login failed for user '<User name>'. The user is not associated with a trusted SQL Server connection.

… then you may have to enable SQL Server Authentication Mode and create or enable a user.

  1. Start Microsoft SQL Server Management Studio Express (SSMSE) and connect to your database server.
  2. In Object Explorer pane, select Properties from your database's context menu. The Server Properties dialog should open.
  3. Select Security page.
  4. Select SQL Server and Windows Authentication Mode check box.
  5. Press OK button to close the dialog.
  6. In Object Explorer pane, expand Security / Logins node.
  7. Select existing user sa. Note that there is a red downward arrow next to that user's image.
  8. View sa's properties. The Login Properties dialog should open.
  9. Select Status page.
  10. Ensure that the Login: Enabled radio button is selected.
  11. Select General page.
  12. Enter a password for this user.
  13. Press OK button to close the dialog.
  14. If you refresh the Object Explorer pane, note that user sa no longer has a red downward arrow.

Finally …

After all these steps, you should be able to connect to your SQL Server Express database using JDBC.

2006-11-20

Java IDEs Jgrasp Eclipse

I had a play with two Java IDEs recently: Jgrasp and Eclipse. For a developer, Jgrasp was small and worked reasonably well. Since I was trying to fix someone else's code, I wished Jgrasp had more features and shortcut keys for debugging. Eclipse is huge but I like the way it automatically parsed my source code to find errors and warnings.

2005-04-26

Java Formatting Currency and Dates

The easiest way to display a double in the local currency is to get an instance of NumberFormat currency formatter and use its format() method. The following example ...
import java.text.NumberFormat;

public class CurrencyFormatExample {
  public static void main(String[] argv) {
    NumberFormat cf = NumberFormat.getCurrencyInstance();
    double cost = 19.51;
    System.out.println("Cost = " + cf.format(cost));
  }
}
... produces ...
Cost = $19.51
Similarly, the easiest way to display a date is to get an instance of a DateFormat date formatter and use its format() method. Choose different types of date formatters to produce shorter or longer output. The following example creates four different data formatters ...
import java.text.DateFormat;
import java.util.Date;

public class DateFormatExample {
  public static void main(String[] argv) {
    DateFormat dfShort = DateFormat.getDateInstance(DateFormat.SHORT);
    DateFormat dfMedium = DateFormat.getDateInstance(DateFormat.MEDIUM);
    DateFormat dfLong = DateFormat.getDateInstance(DateFormat.LONG);
    DateFormat dfFull = DateFormat.getDateInstance(DateFormat.FULL);
    Date today = new Date();
    System.out.println("Today is ...");
    System.out.println(dfShort.format(today));
    System.out.println(dfMedium.format(today));
    System.out.println(dfLong.format(today));
    System.out.println(dfFull.format(today));
  }
}
... and produces ...
Today is ...
26/04/05
26/04/2005
26 April 2005
Tuesday, 26 April 2005