Sample

Schnappinger/aoi/artofillusion.keystroke.KeystrokePreferencesPanel

Human rating uses the original dataset scale.

Human3.31
Lines229

Scores

MethodScoreScaleDataset rank
(0–100)
Posnett00–1; higher is more readable
23.1Δ 14.2
Scalabrino0.6820–1; higher is more readable
33.9Δ 3.4
Dorn0.0260–1; higher is more readable
24.8Δ 12.5
Mi0.5630–1; higher is more readable
47.2Δ 9.9
LLOC102Logical lines; fewer is more readable
24.6Δ 12.7
DeepSeek V4 Pro16.670–20; mean of three runs
59.9Δ 22.6
GPT-6.1 Sol160–20; mean of three runs
38.9Δ 1.7
BTTF0.220–1; higher is more readable
13.2Δ 24.1
Human3.311–4; original rating
37.3

Views

Source code

/* Copyright (C) 2006-2013 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.keystroke; import artofillusion.script.*; import buoy.widget.*; import buoy.event.*; import javax.swing.table.*; import java.awt.event.*; import java.awt.*; import java.util.*; import java.text.*; import artofillusion.ui.*; /** * This class presents a user interface for editing the list of KeystrokeRecords. */ public class KeystrokePreferencesPanel extends FormContainer { private ArrayList<KeystrokeRecord> records; private BTable table; private BButton editButton, addButton, deleteButton; private boolean changed; private int sortColumn = 1; public KeystrokePreferencesPanel() { super(new double [] {1}, new double [] {1, 0}); KeystrokeRecord allRecords[] = KeystrokeManager.getAllRecords(); records = new ArrayList<KeystrokeRecord>(allRecords.length); for (int i = 0; i < allRecords.length; i++) records.add(allRecords[i]); table = new BTable(new KeystrokeTableModel()); table.setColumnWidth(0, 100); table.setColumnWidth(1, 250); table.setColumnsReorderable(false); table.addEventLink(SelectionChangedEvent.class, this, "selectionChanged"); table.addEventLink(MouseClickedEvent.class, this, "tableClicked"); table.getTableHeader().addEventLink(MouseClickedEvent.class, new Object() { void processEvent(MouseClickedEvent ev) { int col = table.findColumn(ev.getPoint()); if (col > -1) { sortColumn = col; sortRecords(); } } }); BScrollPane scroll = new BScrollPane(table, BScrollPane.SCROLLBAR_NEVER, BScrollPane.SCROLLBAR_AS_NEEDED); scroll.setPreferredViewSize(new Dimension(350, table.getRowCount() == 0 ? 150 : 15*table.getRowHeight(0))); add(scroll, 0, 0, new LayoutInfo(LayoutInfo.CENTER, LayoutInfo.BOTH)); RowContainer buttons = new RowContainer(); add(buttons, 0, 1, new LayoutInfo()); buttons.add(editButton = Translate.button("edit", "...", this, "editRecord")); buttons.add(addButton = Translate.button("add", "...", this, "addRecord")); buttons.add(deleteButton = Translate.button("delete", this, "deleteRecords")); selectionChanged(); } /** * Save the changes. */ public void saveChanges() { if (!changed) return; KeystrokeManager.setAllRecords((KeystrokeRecord []) records.toArray(new KeystrokeRecord [records.size()])); try { KeystrokeManager.saveRecords(); } catch (Exception ex) { new BStandardDialog("", Translate.text("errorSavingPrefs", ex.getMessage() == null ? "" : ex.getMessage()), BStandardDialog.ERROR).showMessageDialog(this); } } /** * This is called when the selection in the table changes. */ private void selectionChanged() { int count = table.getSelectedRows().length; editButton.setEnabled(count == 1); deleteButton.setEnabled(count > 0); } /** * This is called when the user clicks on the table. */ private void tableClicked(MouseClickedEvent ev) { if (ev.getClickCount() != 2 || ev.getModifiersEx() != 0) return; editRecord(); } /** * Edit the selected record. */ private void editRecord() { int row = table.getSelectedRows()[0]; KeystrokeRecord record = (KeystrokeRecord) records.get(row); KeystrokeRecord edited = KeystrokeEditor.showEditorDialog(record, UIUtilities.findWindow(this)); if (edited == null) return; records.set(row, edited); sortRecords(); changed = true; } /** * Add a new record. */ private void addRecord() { KeystrokeRecord record = new KeystrokeRecord(0, 0, "", "", ScriptRunner.LANGUAGES[0]); KeystrokeRecord edited = KeystrokeEditor.showEditorDialog(record, UIUtilities.findWindow(this)); if (edited == null) return; records.add(edited); sortRecords(); changed = true; } /** * Delete the selected records. */ private void deleteRecords() { int selected[] = table.getSelectedRows(); Arrays.sort(selected); for (int i = 0; i < selected.length; i++) records.remove(selected[i]); sortRecords(); changed = true; } /** * Resort the list of records by name. */ private void sortRecords() { final Comparator stringComparator = Collator.getInstance(Translate.getLocale()); Collections.sort(records, new Comparator<KeystrokeRecord>() { public int compare(KeystrokeRecord r1, KeystrokeRecord r2) { String s1, s2; if (sortColumn == 0) { s1 = getKeyDescription(r1.getKeyCode(), r1.getModifiers()); s2 = getKeyDescription(r2.getKeyCode(), r2.getModifiers()); } else { s1 = r1.getName(); s2 = r2.getName(); } return stringComparator.compare(s1, s2); } }); ((KeystrokeTableModel) table.getModel()).fireTableDataChanged(); } /** * Get a string describing a keystroke. */ static String getKeyDescription(int code, int modifiers) { if (code == 0) return ""; String keyDesc = KeyEvent.getKeyText(code); if (modifiers != 0) keyDesc = KeyEvent.getKeyModifiersText(modifiers)+"+"+keyDesc; return keyDesc; } /** * This is the model for the table of keystrokes. */ private class KeystrokeTableModel extends AbstractTableModel { public int getRowCount() { return records.size(); } public int getColumnCount() { return 2; } public Object getValueAt(int rowIndex, int columnIndex) { KeystrokeRecord record = (KeystrokeRecord) records.get(rowIndex); if (columnIndex == 1) return record.getName(); return getKeyDescription(record.getKeyCode(), record.getModifiers()); } public String getColumnName(int column) { return (column == 1 ? Translate.text("Name") : Translate.text("Key")); } } }

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.8619.852−284.455
Source linesThe number of non-empty source lines.229+91.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.882−7.323

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

Score0.682

Feature contributions

FeatureValueContribution
(log-odds)
Comment layout frequencyHow frequently the layout switches between lines containing only comments or whitespace and lines containing code.229−7.072
Indentation frequencyHow rapidly indentation changes from line to line.200+6.181
Number layout frequencyHow rapidly the number of numeric values per line changes through the code.201−4.191
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.160.991−3.154
Identifier layout (vertical)How rapidly the visual pattern of identifier characters changes from top to bottom.228.877+2.789
Comment layout (horizontal)How rapidly the visual pattern of comment characters changes from left to right.160.996+1.793
Operator visual areaThe share of the code’s visual area occupied by operators such as +, =, and *.0.103−0.057

Intercept 0.07 + feature contributions = -3.64 (log-odds).
Score = sigmoid(-3.64) = 0.026.

Score0.563
Score102
Run 1

The code is well-structured and highly readable. It follows clear separation of concerns with distinct methods for actions, good use of Javadoc, and consistent naming conventions. The class is organized logically, with UI construction separated from event handlers and data management. Nesting is minimal, with early returns reducing complexity. Action granularity is mostly one action per line, particularly in the method bodies. The code length is appropriate for the functionality, though some methods like the constructor are slightly long. The anonymous inner class for table header clicks is slightly less readable but still acceptable. The table model inline class is cleanly separated. The sorting logic uses comparators effectively. Overall, the code demonstrates strong readability with clear intent, natural flow, and good practices.

Run 2

The code is well-structured and highly readable. It follows a logical class organization with clear method separation and descriptive Javadoc comments. The constructor initializes UI components in a straightforward sequence, though the anonymous inner class for table header clicks adds slight nesting. Methods are concise and focused on single responsibilities, with early returns reducing indentation. Naming is clear and intent is evident throughout. The table model inner class is neatly separated and minimal. One minor concern: the addRecord method uses multiple operations per line when creating and editing the record, but overall the code maintains excellent readability with proper spacing, consistent formatting, and clear action granularity.

Run 3

The code is generally well-structured and readable. It has a clear purpose, logical organization, and good method naming that reflects intent. The class is relatively flat with minimal deep nesting, and each method performs a focused action. However, there are some areas that could be improved: the constructor is somewhat long and does multiple setup tasks at once, action granularity could be better in places (e.g., multiple operations in single lines), and some anonymous inner classes add slight complexity. Variable naming is clear, and Javadoc comments help explain purpose. Overall, an experienced Java developer would find this code understandable, though it could benefit from slightly better separation of UI setup logic.

Run 1

Code Structure: Responsibilities are organized into focused methods, with a separate inner table model; the constructor mixes UI setup and event wiring. Nesting: Mostly shallow, with early returns keeping handlers flat; anonymous event handlers and comparators introduce modest nesting. Clarity of intent: Descriptive method names and comments explain the purpose, though numeric column identifiers, string-based event links, and the inaccurate sorting comment reduce clarity. Code length: Generally concise, but redundant casts, repetitive documentation, and verbose initialization add noise. Action granularity: Most lines perform one action, although button creation combines assignment with insertion, and some dialog expressions pack several operations together. Reading flow: Consistent formatting and a natural progression from initialization through actions to helper methods make the class easy to follow. Long lines, wildcard imports, and occasional omitted braces slightly hinder scanning.

Run 2

Code Structure: Well organized into focused event handlers, persistence, sorting, and an inner table model, though the constructor combines substantial UI setup and event wiring. Nesting: Mostly shallow, with early returns keeping handlers flat; anonymous classes add some complexity. Clarity of intent: Descriptive method names and comments explain responsibilities, but numeric column identifiers, string-based event links, and a sorting comment that mentions only names reduce precision. Code length: Generally concise, although repetitive documentation, redundant casts, and verbose anonymous classes add clutter. Action granularity: Most lines perform one action, but button creation combines assignment and insertion, and several dialog/layout expressions are dense. Reading flow: Consistent formatting and logical method ordering make the class easy to follow; long statements and inline callbacks occasionally interrupt the flow.

Run 3

Code Structure: Well-organized into focused event handlers, persistence logic, sorting, and an inner table model, though the constructor mixes initialization, layout, and event wiring. Nesting: Mostly shallow, with early returns keeping handlers flat; anonymous callbacks and the sorting comparator add moderate nesting. Clarity of intent: Descriptive method names and comments explain most operations, but numeric column identifiers, string-based event links, and a sorting comment that mentions only names reduce clarity. Code length: Generally concise, although repetitive editor handling, redundant casts, and boilerplate add some noise. Action granularity: Most lines perform one action, but button creation combines assignment and insertion, and several long expressions combine multiple operations. Reading flow: Methods follow a natural setup-to-interaction-to-model progression with consistent formatting; long constructor and dialog expressions slightly interrupt scanning.