Sample

Schnappinger/aoi/artofillusion.ui.ToolPalette

Human rating uses the original dataset scale.

Human2.49
Lines294

Scores

MethodScoreScaleDataset rank
(0–100)
Posnett00–1; higher is more readable
18.7Δ 4.2
Scalabrino0.7260–1; higher is more readable
43.8Δ 29.3
Dorn0.0510–1; higher is more readable
29.0Δ 14.5
Mi0.5510–1; higher is more readable
41.9Δ 27.4
LLOC165Logical lines; fewer is more readable
16.2Δ 1.7
DeepSeek V4 Pro15.330–20; mean of three runs
41.3Δ 26.7
GPT-6.1 Sol160–20; mean of three runs
38.9Δ 24.4
BTTF0.3090–1; higher is more readable
21.5Δ 6.9
Human2.491–4; original rating
14.5

Views

Source code

/* Copyright (C) 1999-2006 by Peter Eastman This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. */ package artofillusion.ui; import artofillusion.*; import buoy.event.*; import buoy.widget.*; import java.awt.*; /** A ToolPalette is drawn as a grid of images, one for each EditingTool that is added to the palette. It allows a single tool to be selected at any time. */ public class ToolPalette extends CustomWidget { private int width, height, numTools, selected, lastSelected, defaultTool; private EditingTool tool[]; private Dimension maxsize; /** Create a new ToolPalette. w and h give the width and height of the tool palette, measured in icons. */ public ToolPalette(int w, int h) { width = w; height = h; tool = new EditingTool [w*h]; numTools = 0; selected = 0; defaultTool = 0; maxsize = new Dimension(0, 0); addEventLink(MousePressedEvent.class, this, "mousePressed"); addEventLink(MouseClickedEvent.class, this, "mouseClicked"); addEventLink(MouseEnteredEvent.class, this, "mouseEntered"); addEventLink(MouseExitedEvent.class, this, "mouseExited"); addEventLink(MouseMovedEvent.class, this, "mouseMoved"); addEventLink(RepaintEvent.class, this, "paint"); addEventLink(ToolTipEvent.class, this, "showToolTip"); setBackground(ThemeManager.getPaletteBackgroundColor()); } /** Add a new tool. */ public void addTool(EditingTool t) { addTool(numTools, t); } /** Add a new tool. */ public void addTool(int position, EditingTool t) { if (numTools == tool.length) { // We need to extend the palette. height++; EditingTool newTool[] = new EditingTool [width*height]; System.arraycopy(tool, 0, newTool, 0, tool.length); tool = newTool; invalidateSize(); } for (int i = numTools; i > position; i--) tool[i] = tool[i-1]; tool[position] = t; numTools++; int buttonMargin = ThemeManager.getButtonMargin(); int paletteMargin = ThemeManager.getPaletteMargin(); int w = t.getButton().getWidth() + 2*buttonMargin; int h = t.getButton().getHeight() + 2*buttonMargin; if (w > maxsize.width) maxsize.width = w; if (h > maxsize.height) maxsize.height = h; for (int i = 0; i < numTools; i++) tool[i].getButton().setPosition((i%width)*maxsize.width + paletteMargin + buttonMargin, (i/width)*maxsize.height + paletteMargin + buttonMargin); if (numTools == 1) t.activate(); } /** Get the number of tools in palette. */ public int getNumTools() { return numTools; } /** Get a tool by index. */ public EditingTool getTool(int index) { return tool[index]; } /** Get the default tool. */ public EditingTool getDefaultTool() { return tool[defaultTool]; } /** Set the default tool. */ public void setDefaultTool(EditingTool t) { for (int i = 0; i < tool.length; i++) if (tool[i] == t) defaultTool = i; } /** Return the number of the currently selected tool. */ public int getSelection() { return selected; } /** Return the currently selected tool. */ public EditingTool getSelectedTool() { return tool[selected]; } private void paint(RepaintEvent ev) { Graphics2D g = ev.getGraphics(); g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); int paletteMargin = ThemeManager.getPaletteMargin(); g.setColor(ThemeManager.getPaletteBackgroundColor()); g.fillRoundRect(0, 0, width*maxsize.width + 2*paletteMargin, height*maxsize.height + 2*paletteMargin, 8, 8); //So as to ensure graphical consistency, buttons must be drawn following a certain order: //normal buttons first for (int i = 0; i < numTools; i++) if (!tool[i].getButton().isSelected() && !tool[i].getButton().isHighlighted()) tool[i].getButton().paint(g); //highlighted buttons next for (int i = 0; i < numTools; i++) if (!tool[i].getButton().isSelected() && tool[i].getButton().isHighlighted()) tool[i].getButton().paint(g); //then the selected one. for (int i = 0; i < numTools; i++) if (tool[i].getButton().isSelected()) tool[i].getButton().paint(g); } private void showToolTip(ToolTipEvent ev) { int i = findClickedTool(ev.getPoint()); if (i > -1 && i < numTools) { String text = tool[i].getToolTipText(); if (text == null) BToolTip.hide(); else new BToolTip(text).processEvent(ev); } } public Dimension getPreferredSize() { int paletteMargin = ThemeManager.getPaletteMargin(); return new Dimension(width*maxsize.width+2*paletteMargin, height*maxsize.height+2*paletteMargin); } public Dimension getMinimumSize() { return getPreferredSize(); } private void mousePressed(MousePressedEvent e) { int i = findClickedTool(e.getPoint()); if (i > -1 && i < numTools && i != selected) { if (selected < tool.length) tool[selected].deactivate(); selected = lastSelected = i; repaint(); tool[i].activate(); } } private void mouseClicked(MouseClickedEvent e) { int i = findClickedTool(e.getPoint()); if (i > -1 && i < numTools && e.getClickCount() == 2) tool[i].iconDoubleClicked(); } private void mouseEntered(MouseEnteredEvent ev) { int t = findClickedTool(ev.getPoint()); for (int i = 0; i < numTools; i++) tool[i].getButton().setHighlighted(t == i); repaint(); } private void mouseExited() { for (int i = 0; i < numTools; i++) tool[i].getButton().setHighlighted(false); repaint(); } private void mouseMoved(MouseMovedEvent ev) { int t = findClickedTool(ev.getPoint()); for (int i = 0; i < numTools; i++) tool[i].getButton().setHighlighted(t == i); repaint(); } private int findClickedTool(Point p) { Rectangle r = new Rectangle(); for (int i = 0; i < numTools; i++) { Point pos = tool[i].getButton().getPosition(); r.x = pos.x; r.y = pos.y; r.width = tool[i].getButton().getWidth(); r.height = tool[i].getButton().getHeight(); if (r.contains(p)) return i; } return -1; } /** Change the currently selected tool. */ public void selectTool(EditingTool which) { selectToolInternal(which); lastSelected = selected; } /** This is used internally to actually change the selected tool. */ private void selectToolInternal(EditingTool which) { for (int i = 0; i < numTools; i++) if (tool[i] == which) { tool[selected].deactivate(); selected = i; repaint(); tool[i].activate(); } } /** Allow the user to change tools with the keyboard. */ public void keyPressed(KeyPressedEvent ev) { int code = ev.getKeyCode(); int newtool; if (code == KeyPressedEvent.VK_LEFT) newtool = selected-1; else if (code == KeyPressedEvent.VK_RIGHT) newtool = selected+1; else if (code == KeyPressedEvent.VK_UP) newtool = selected-width; else if (code == KeyPressedEvent.VK_DOWN) newtool = selected+width; else return; if (newtool < 0) newtool += numTools; if (newtool >= numTools) newtool -= numTools; tool[selected].deactivate(); selected = lastSelected = newtool; repaint(); tool[selected].activate(); } /** Calling this method will toggle between the default tool and the last tool which was explicitly selected. */ public void toggleDefaultTool() { selectToolInternal(tool[selected == lastSelected ? defaultTool : lastSelected]); } }

Loading feature diagnosis…

Source regions

Feature contributions

Feature contributions

FeatureValueContribution
(log-odds)
Halstead volumeHow much symbolic information the code contains. It combines the total number of operators and values with the number of distinct ones.11404.755−376.357
Source linesThe number of non-empty source lines.294+117.6
Byte entropyHow varied the bytes in the source text are. Repeated bytes give a lower value; a more even mixture gives a higher value.4.8−7.2

Intercept 8.87 + feature contributions = -257.087 (log-odds).
Score = sigmoid(-257.087) = 0.

Score0.726

Feature contributions

FeatureValueContribution
(log-odds)
Comment layout frequencyHow frequently the layout switches between lines containing only comments or whitespace and lines containing code.294−9.373
Indentation frequencyHow rapidly indentation changes from line to line.278+8.879
Number layout frequencyHow rapidly the number of numeric values per line changes through the code.278−5.958
Identifier layout (vertical)How rapidly the visual pattern of identifier characters changes from top to bottom.292.85+3.684
Identifier layout (horizontal)How rapidly the visual pattern of identifier characters changes from left to right. It measures spatial frequency, not the meaning of the names.111.983−1.078
Comment layout (horizontal)How rapidly the visual pattern of comment characters changes from left to right.111.966+1.002
Operator visual areaThe share of the code’s visual area occupied by operators such as +, =, and *.0.113−0.152

Intercept 0.07 + feature contributions = -2.927 (log-odds).
Score = sigmoid(-2.927) = 0.051.

Score0.551
Score165
Run 1

The code has clear class-level documentation and generally descriptive method names, aiding intent. However, it suffers from several readability issues. The `addTool` method is overly long, combining array resizing, element shifting, size calculation, and UI updates with multiple nested loops and conditionals. Action granularity is mixed; some methods follow one-action-per-line, while others pack multiple statements per line. Nesting is moderate but becomes dense in `paint` and `addTool`. The reading flow is disrupted by deep, multi-purpose loops and comments that explain 'what' rather than 'why'. Code structure is acceptable, but methods like `mousePressed`, `mouseEntered`, and `mouseMoved` duplicate logic, indicating a lack of abstraction. Overall, the code is understandable but requires effort due to verbose methods and scattered responsibilities.

Run 2

The code has clear structure with logical method grouping and Javadoc comments. It is mostly flat with minimal nesting and follows a natural reading flow. However, there are several places where action granularity could be improved: multiple operations are chained on single lines (e.g., chained method calls like `tool[i].getButton().setPosition()`), and some lines exceed comfortable length (e.g., the `fillRoundRect` call and `getPreferredSize` return). The variable naming is concise but sometimes cryptic (`r`, `t`, `ev`), and the three-pass paint logic with inline comments is somewhat repetitive. The `selectToolInternal` method has an unnecessary `if` check and missing early return, adding a minor nesting level. Overall, the code is quite readable and maintainable, but would benefit from slight refactoring for line lengths and granularity.

Run 3

The code has good structure with clear separation of methods, each handling a specific event or query. Nesting is generally shallow, though the paint method uses three sequential loops for drawing order, which is reasonable. Intent is mostly clear, with descriptive method names and comments explaining non-obvious logic like drawing order. Code length is moderate but some methods like addTool and paint could be split further. Action granularity is good—most lines perform one action, especially in event handlers. Reading flow is natural, matching typical UI component patterns. Minor issues: magic numbers in paint (8, 8 for corner radius), some duplicated logic in mouseEntered and mouseMoved, and slightly inconsistent use of comments in selectToolInternal. Overall, readable code that would be easy to maintain.

Run 1

Code Structure: Well organized into focused methods for tool management, rendering, sizing, and event handling, although selection and highlighting logic is duplicated. Nesting: Generally shallow, with simple loops and conditionals; omitted braces slightly hinder scanning. Clarity of intent: Descriptive method names and useful comments explain most behavior, but abbreviated variables, grouped fields, and the selected/lastSelected relationship require extra attention. Code length: Mostly concise, though repeated button access, rendering loops, and mouse handlers add verbosity. Action granularity: Usually one operation per line, with chained assignments and grouped declarations as exceptions. Reading flow: Predictable formatting and small methods support natural reading, but inconsistent indentation, tightly spaced arithmetic, long expressions, and string-based event registration reduce ease of navigation.

Run 2

Code Structure: Well-organized into focused methods for tool management, rendering, selection, and event handling, though selection and highlighting logic are duplicated. Nesting: Mostly shallow, with straightforward loops and conditionals; omitted braces slightly reduce scanability. Clarity of intent: Descriptive method names and documentation explain the palette's behavior, but abbreviated variables, grouped fields, and subtle selected/lastSelected interactions require extra attention. Code length: Generally concise for its functionality, although repeated button access, highlighting handlers, and selection updates could be consolidated. Action granularity: Most lines perform one action; chained assignments such as selected = lastSelected = i are minor exceptions. Reading flow: Initialization, accessors, and handlers follow a reasonably natural progression, but inconsistent indentation, dense arithmetic expressions, and placement of selection methods after mouse handlers interrupt the flow slightly.

Run 3

Code Structure: Well organized into focused methods for tool management, rendering, selection, and event handling, though selection and highlighting logic are duplicated. Nesting: Generally shallow, with straightforward loops and conditionals; omitted braces slightly hinder scanning. Clarity of intent: Descriptive method names and useful documentation explain the palette's purpose and rendering order. Short variable names, grouped fields, and subtle selected/lastSelected state transitions reduce clarity. Code length: Mostly concise, but repeated button access, rendering loops, and identical mouse-enter/move handlers add avoidable repetition. Action granularity: Most lines perform one action, although chained assignments combine state updates and some expressions pack substantial layout calculations into one line. Reading flow: Methods are easy to follow locally, but inconsistent indentation, tight operator spacing, long expressions, and scattered selection updates interrupt an otherwise natural flow.