Sample

Schnappinger/aoi/artofillusion.ui.DefaultToolButton

Human rating uses the original dataset scale.

Human4
Lines186

Scores

MethodScoreScaleDataset rank
(0–100)
Posnett00–1; higher is more readable
37.1Δ 57.9
Scalabrino0.7390–1; higher is more readable
45.9Δ 49.2
Dorn0.1610–1; higher is more readable
38.3Δ 56.8
Mi0.580–1; higher is more readable
54.5Δ 40.6
LLOC53Logical lines; fewer is more readable
38.3Δ 56.8
DeepSeek V4 Pro13.670–20; mean of three runs
26.9Δ 68.2
GPT-6.1 Sol15.330–20; mean of three runs
30.7Δ 64.4
BTTF0.3420–1; higher is more readable
26.1Δ 69.0
Human41–4; original rating
95.0

Views

Source code

/* Copyright (C) 2007 by Fran�ois Guillet 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.util.IconGenerator; import java.awt.*; import java.awt.image.BufferedImage; import javax.swing.ImageIcon; import java.util.HashMap; /** * This ToolButton is the classic button with one icon for standard representation * and another one for selected state. * * @author Francois Guillet * */ public class DefaultToolButton extends ToolButton { protected Image icon; protected Image selectedIcon; /* public DefaultToolButton(Object owner, String iconFileName, String selectedIconFilename) { this(owner, ThemeManager.getIcon(iconFileName), ThemeManager.getIcon(selectedIconFilename)); } */ /** * create a DefaultToolButton for the specified owner, and the icon * specified by the <i>image</i>, by applying the correct style to the * image to generate theme-consistent <i>normal</i> and <i>selected</i> * icons. * * This ctor is the preferred ctor, as it ensures the greatest consistency * of all icons with the theme. * * @param owner the owning object for this button * * @param image the image to use with the style to generate the normal and * selected icons for this button. */ public DefaultToolButton(Object owner, ImageIcon image) { super(owner); ThemeManager.ButtonStyle bstyle = ThemeManager.getButtonStyle(owner); if (bstyle != null) { try { icon = applyStyle(bstyle, "normal", owner, image); selectedIcon = applyStyle(bstyle, "selected", owner, image); } catch (Exception e) { System.out.println("Applying style: " + e); } } // if the style failed to apply, just use the icon as it is if (icon == null || icon.getWidth(null) <= 0) icon = image.getImage(); // last resort: set icon to notFoundIcon if (icon == null || icon.getWidth(null) <= 0) icon = ThemeManager.getNotFoundIcon(owner).getImage(); // selectedIcon defaults to icon with a red "wash" if (selectedIcon == null) { selectedIcon = IconGenerator.copy(icon); IconGenerator.multiply((BufferedImage) selectedIcon, 1.0f, 1.0f, 0.5f, 0.5f); } width = icon.getWidth(null); height = icon.getHeight(null); } /** * create a new DefaultToolButton using the specified icons for * <i>normal</i> and <i>selected</i> icons. * *<b><em>No</em> style is applied - the icons are used as-is. * * This is the least-preferred ctor, since it applies no consistency * at all, and relies on the icon creator to have made the icons * consistent. This normally works well for icons that are part of the * theme, but usually works very poorly for icons associated with plugins. * * @param icon the icon to use for normal button display * @param selectedIcon the icon to use for selected display. */ public DefaultToolButton(Object owner, ImageIcon icon, ImageIcon selectedIcon) { super(owner); this.icon = icon.getImage(); this.selectedIcon = selectedIcon.getImage(); height = icon.getIconHeight(); width = icon.getIconWidth(); } public void paint(Graphics2D g) { switch(state) { case NORMAL_STATE: case HIGHLIGHTED_STATE: g.drawImage(icon, position.x, position.y, null); break; case SELECTED_STATE: g.drawImage(selectedIcon, position.x, position.y, null); break; } } /** * apply a style for the specified type and owner, to the specified * icon url. * * If the style defined no <code>type.icon</code> attribute, then * a definition is generated using the <code>type.background</i> and * <code>type.overlay</code> attributes. If no style definition can * be foudn or generated, the icon from <i>image</i> is returned. * * @param style the ButtonStyle to apply * @param type the type of icon to create. Current values are * <em>normal</em> and <em>selected</em>. * In theory <em>highlighted</em> can also be specified, but * currently no code recognises this type. * * @param owner the owner of this style. * * @param image the image to use with the style to generate the final * icon. * * @return the generated icon. */ public Image applyStyle(ThemeManager.ButtonStyle style, String type, Object owner, ImageIcon image) throws Exception { // can default the macro from other attributes String macro = style.attributes.get(type + ".icon"); if (macro == null || macro.length() == 0) { StringBuffer sb = new StringBuffer(64); String att = style.attributes.get(type + ".background"); if (att == null) att = style.attributes.get("background"); if (att != null) { sb.append(att); sb.append("; {icon};"); att = (String) style.attributes.get(type + ".overlay"); if (att == null) att = style.attributes.get("overlay"); if (att != null) sb.append(att); macro = sb.toString(); } else // no macro possible, just return the image return image.getImage(); } // we're still here, so apply the style... // initialise the namespace HashMap<String, Object> namespace = new HashMap<String, Object>(style.attributes); if (image != null) { Image img = image.getImage(); namespace.put("{icon}", img); namespace.put('{' + type + ".icon}", img); } namespace.put("{owner}", owner); // get the classloader from the selected theme ClassLoader loader = ThemeManager.getSelectedTheme().loader; // return the result of applying the style return IconGenerator.apply(macro, null, namespace, loader, style.width, style.height); } }

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.4436.267−146.397
Source linesThe number of non-empty source lines.186+74.4
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.58−6.87

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

Score0.739

Feature contributions

FeatureValueContribution
(log-odds)
Comment layout frequencyHow frequently the layout switches between lines containing only comments or whitespace and lines containing code.185−5.514
Indentation frequencyHow rapidly indentation changes from line to line.112+3.137
Identifier layout (vertical)How rapidly the visual pattern of identifier characters changes from top to bottom.184.765+2.173
Number layout frequencyHow rapidly the number of numeric values per line changes through the code.112−2.149
Comment layout (horizontal)How rapidly the visual pattern of comment characters changes from left to right.100.946+0.824
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.100.952−0.611
Operator visual areaThe share of the code’s visual area occupied by operators such as +, =, and *.0.054+0.416

Intercept 0.07 + feature contributions = -1.653 (log-odds).
Score = sigmoid(-1.653) = 0.161.

Score0.58
Score53
Run 1

The code is fairly readable due to its clear documentation and logical structure. Each method has a distinct purpose, and Javadoc comments explain intent and edge cases. However, there are issues with readability. The `applyStyle` method is overly long and mixes multiple responsibilities: macro generation, namespace setup, and style application. It uses string concatenation with `StringBuffer`, which feels dated and verbose. Conditional branches add moderate nesting but are not excessive. Some action granularity is poor—multiple operations are packed into single lines, such as `att = (String) style.attributes.get(...)`. There is some inconsistency in bracing style and alignment. The commented-out constructor and typo in comments ('foudn') slightly detract from polish. The `paint` method is clear and concise. Overall, the code is maintainable but could benefit from refactoring `applyStyle` into smaller helper methods and reducing conditional density.

Run 2

The code is generally readable with clear class purpose, good documentation, and logical grouping of methods and constructors. It uses an appropriate level of abstraction with helper methods (applyStyle) and maintains one action per line for the most part. However, there are some readability drawbacks: the applyStyle method has multiple nested if-else statements that increase complexity, some variable names are vague (e.g., 'att', 'sb', 'macro'), and there is commented-out code left in the class. The paint method uses a switch with fallthrough cases that could be clearer with an if-statement. The error handling with System.out.println is weak but not a readability issue per se. Overall structure is sound, but nesting and slightly inconsistent naming prevent a higher score.

Run 3

The code is generally structured and readable, with clear class and method names, and good use of comments to explain the constructors and the applyStyle method. However, readability is reduced by several factors: the paint() method has a switch statement with cases that could be better organized, and the applyStyle method has a fairly long chain of nested conditionals and string concatenations that makes the logic somewhat tangled. There are also inconsistencies in style, such as the commented-out constructor and the use of both /* */ and /** */ comments. Overall, the code is understandable but could benefit from cleaner separation of concerns and reduced nesting.

Run 1

Code Structure: Constructors, rendering, and style application are logically separated, though applyStyle combines macro construction and execution. Nesting: Mostly shallow, with moderate nesting in style fallback logic. Clarity of intent: Descriptive methods, fields, and fallback comments explain the purpose; abbreviated variables such as att and sb, outdated documentation, and broad exception handling reduce clarity. Code length: Implementation is reasonably concise, but lengthy Javadocs and a commented-out constructor add clutter. Action granularity: Most statements perform one action per line; inline conditionals compress checks and assignments slightly. Reading flow: Initialization proceeds naturally through styling, fallbacks, and dimensions, while rendering is straightforward. Inconsistent indentation, brace placement, malformed documentation tags, and switching between naming styles interrupt an otherwise coherent flow.

Run 2

Code Structure: Constructors, painting, and style application are logically separated, although applyStyle combines macro construction and rendering setup. Nesting: Mostly shallow, with moderate nesting in style generation and constructor error handling. Clarity of intent: Descriptive methods, fields, and fallback comments clarify behavior; abbreviated variables, magic color values, and the macro syntax require extra interpretation. Code length: Implementation is reasonably concise, but lengthy documentation, redundant comments, and a commented-out constructor add clutter. Action granularity: Most lines perform one action, though inline conditionals compress checks and assignments onto single lines. Reading flow: Initialization proceeds naturally from styling to fallbacks and dimensions, and painting is straightforward. Inconsistent indentation, brace placement, malformed documentation tags, and outdated comments interrupt an otherwise understandable flow.

Run 3

Code Structure: Constructors, rendering, and style generation are logically separated, although applyStyle combines macro construction and execution. Nesting: Mostly shallow; nested conditionals in macro generation and constructor exception handling add moderate complexity. Clarity of intent: Descriptive method and field names, documentation, and fallback comments explain the purpose well, but abbreviated variables such as bstyle, att, and sb reduce clarity. Some documentation is outdated or contains malformed markup and typos. Code length: Implementation is reasonably concise, but verbose documentation and a commented-out constructor add clutter. Action granularity: Most lines perform one action; inline conditional assignments slightly reduce scanability. Reading flow: Initialization, fallbacks, and rendering follow a natural sequence. Inconsistent indentation, brace placement, and spacing interrupt an otherwise straightforward reading experience.