principleMinor
Approach to programmatically building hierarchical GUI components
Viewed 0 times
buildingcomponentshierarchicalguiapproachprogrammatically
Problem
At work I am developing an application using hand-coded Swing, and I've found that I have an easier time reading, writing, and maintaining hierarchical component creation using code blocks like:
So I wondered what that would look like using F# and WinForms, and I translated this code example (go to "Browse Code" tab, then click on F# -> editor.fsx in tree view) in two ways and I'd like feedback on which of the following two ways seems better. The first uses code blocks like the approach shown in Swing, and I think it is nice but a bit cluttered with
The second approach is interesting because it takes advantage of the fact that in F# everything is an expression, but it seems a little harder for me to follow and I'm not sure if that's just because I'm used to the code block approach:
```
open System
open System.Windows.Forms
let form = new Form()
form.Width form.Close())
miQuit
) |> ignore
JPanel mainPanel = new JPanel(new BorderLayout());
{
JLabel centerLabel = new JLabel();
centerLabel.setText("Hello World");
mainPanel.add(centerLabel, BorderLayout.CENTER);
}
{
JPanel southPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 0,0));
{
JLabel label1 = new JLabel();
label1.setText("Hello");
southPanel.add(label1);
}
{
JLabel label2 = new JLabel();
label2.setText("World");
southPanel.add(label2);
}
mainPanel.add(southPanel, BorderLayout.SOUTH);
}So I wondered what that would look like using F# and WinForms, and I translated this code example (go to "Browse Code" tab, then click on F# -> editor.fsx in tree view) in two ways and I'd like feedback on which of the following two ways seems better. The first uses code blocks like the approach shown in Swing, and I think it is nice but a bit cluttered with
begin ... end everywhere:open System
open System.Windows.Forms
let form = new Form()
form.Width form.Close())
mFile.MenuItems.Add(miQuit) |> ignore
end
mMain.MenuItems.Add(mFile) |> ignore
end
form.Menu <- mMain
end
begin
// RichTextView
let textB = new RichTextBox()
textB.Dock <- DockStyle.Fill
textB.Text <- "Hello World\n\nOK."
form.Controls.Add(textB)
endThe second approach is interesting because it takes advantage of the fact that in F# everything is an expression, but it seems a little harder for me to follow and I'm not sure if that's just because I'm used to the code block approach:
```
open System
open System.Windows.Forms
let form = new Form()
form.Width form.Close())
miQuit
) |> ignore
Solution
Here is my take on your code:
I tried to improve by assigning properties directly in the constructor call. I also used nested let declarations to reflect the hierarchy. Finally, I used indentation instead of explicit begin/end or parens to delimit blocks.
Note also how I used mMain within the declaration of the top-level mMain. Others might have used tmp, I think using the same name makes the intent clear. It might be a bit confusing for new-comers, though.
open System
open System.Windows.Forms
let form =
new Form(
Width = 400,
Height = 300,
Visible = true,
Text = "Hello World Form")
// Menu bar, menus
let mMain =
let miQuit = new MenuItem("&Quit")
miQuit.Click.Add(fun _ -> form.Close())
let mFile = new MenuItem("&File")
mFile.MenuItems.Add(miQuit) |> ignore
let mMain = new MainMenu()
mMain.MenuItems.Add(mFile) |> ignore
mMain
form.Menu <- mMain
// RichTextView
let textB = new RichTextBox(Dock = DockStyle.Fill, Text = "Hello World\n\nOK.")
form.Controls.Add(textB)I tried to improve by assigning properties directly in the constructor call. I also used nested let declarations to reflect the hierarchy. Finally, I used indentation instead of explicit begin/end or parens to delimit blocks.
Note also how I used mMain within the declaration of the top-level mMain. Others might have used tmp, I think using the same name makes the intent clear. It might be a bit confusing for new-comers, though.
Code Snippets
open System
open System.Windows.Forms
let form =
new Form(
Width = 400,
Height = 300,
Visible = true,
Text = "Hello World Form")
// Menu bar, menus
let mMain =
let miQuit = new MenuItem("&Quit")
miQuit.Click.Add(fun _ -> form.Close())
let mFile = new MenuItem("&File")
mFile.MenuItems.Add(miQuit) |> ignore
let mMain = new MainMenu()
mMain.MenuItems.Add(mFile) |> ignore
mMain
form.Menu <- mMain
// RichTextView
let textB = new RichTextBox(Dock = DockStyle.Fill, Text = "Hello World\n\nOK.")
form.Controls.Add(textB)Context
StackExchange Code Review Q#1773, answer score: 4
Revisions (0)
No revisions yet.