Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ Tracked Stats:

Purpose: To track afk metrics to compare between activies and methods. Similar to tracking DPS and Kills/hr.

Session history shows your most recent sessions first. Click a session name to rename it. Sessions can be copied to clipboard or deleted (with confirmation).
Session history shows your most recent sessions first. Click a session name to rename it. Sessions can be copied to clipboard or deleted (with confirmation). The Start/Stop buttons and live stats stay pinned in place; only the history list scrolls when it grows long.

## Wiki Guide

Expand Down
Binary file modified panel-preview.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
96 changes: 67 additions & 29 deletions src/main/java/com/afkstatstracker/AfkStatsTrackerPanel.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.Toolkit;
import java.awt.datatransfer.StringSelection;
Expand All @@ -30,6 +31,7 @@
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.ImageIcon;
import javax.swing.Scrollable;
import javax.swing.SwingConstants;
import javax.swing.Timer;
import net.runelite.client.ui.ColorScheme;
Expand All @@ -55,10 +57,14 @@ public class AfkStatsTrackerPanel extends PluginPanel
private DistanceIndicator distanceIndicator;

private JPanel historyContainer;
private JScrollPane historyScrollPane;
private boolean historyExpanded = true;

public AfkStatsTrackerPanel(AfkStatsTrackerPlugin plugin, SessionHistoryManager sessionHistoryManager)
{
// wrap=false: we manage our own scroll so the buttons/stats stay pinned and only history data scrolls
super(false);

this.plugin = plugin;
this.sessionHistoryManager = sessionHistoryManager;

Expand All @@ -67,9 +73,9 @@ public AfkStatsTrackerPanel(AfkStatsTrackerPlugin plugin, SessionHistoryManager
timer = new Timer(1000, e -> updateStats());
timer.setRepeats(true);

// Main content panel
JPanel contentPanel = new JPanel();
contentPanel.setLayout(new BoxLayout(contentPanel, BoxLayout.Y_AXIS));
// Pinned top panel (buttons + stats + history header) — never scrolls
JPanel topPanel = new JPanel();
topPanel.setLayout(new BoxLayout(topPanel, BoxLayout.Y_AXIS));

// Button panel
JPanel buttonPanel = new JPanel(new GridLayout(1, 2, 5, 0));
Expand Down Expand Up @@ -128,14 +134,22 @@ public AfkStatsTrackerPanel(AfkStatsTrackerPlugin plugin, SessionHistoryManager
statsPanel.add(distanceIndicator);
statsPanel.setMaximumSize(new Dimension(Integer.MAX_VALUE, statsPanel.getPreferredSize().height));

// History section
JPanel historySection = createHistorySection();
// History header (pinned) + scrollable data area
JPanel historyHeader = createHistoryHeader();

historyContainer = new ScrollablePanel();

contentPanel.add(buttonPanel);
contentPanel.add(statsPanel);
contentPanel.add(historySection);
historyScrollPane = new JScrollPane(historyContainer);
historyScrollPane.setBorder(BorderFactory.createEmptyBorder(5, 0, 0, 0));
historyScrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
refreshHistoryPanel();

add(contentPanel, BorderLayout.NORTH);
topPanel.add(buttonPanel);
topPanel.add(statsPanel);
topPanel.add(historyHeader);

add(topPanel, BorderLayout.NORTH);
add(historyScrollPane, BorderLayout.CENTER);
}

private JPanel createStatCard(String title, String tooltip)
Expand Down Expand Up @@ -192,13 +206,11 @@ private JPanel createSessionCard()
return card;
}

private JPanel createHistorySection()
private JPanel createHistoryHeader()
{
JPanel section = new JPanel(new BorderLayout());
section.setBorder(BorderFactory.createEmptyBorder(10, 0, 0, 0));

// Header with toggle
JPanel header = new JPanel(new BorderLayout());
header.setBorder(BorderFactory.createEmptyBorder(10, 0, 0, 0));

JLabel headerLabel = new JLabel("▼ Session History");
headerLabel.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
headerLabel.addMouseListener(new MouseAdapter()
Expand All @@ -208,25 +220,12 @@ public void mouseClicked(MouseEvent e)
{
historyExpanded = !historyExpanded;
headerLabel.setText((historyExpanded ? "▼" : "▶") + " Session History");
historyContainer.setVisible(historyExpanded);
historyScrollPane.setVisible(historyExpanded);
revalidate();
}
});
header.add(headerLabel, BorderLayout.WEST);

// History container
historyContainer = new JPanel();
historyContainer.setLayout(new BoxLayout(historyContainer, BoxLayout.Y_AXIS));

JScrollPane scrollPane = new JScrollPane(historyContainer);
scrollPane.setPreferredSize(new Dimension(0, 300));
scrollPane.setBorder(null);

section.add(header, BorderLayout.NORTH);
section.add(scrollPane, BorderLayout.CENTER);

refreshHistoryPanel();
return section;
return header;
}

public void refreshHistoryPanel()
Expand Down Expand Up @@ -464,6 +463,45 @@ public void stopTimer()
}
}

// Vertical list whose width follows the viewport, so rows shrink/truncate instead of forcing a horizontal scrollbar
private static class ScrollablePanel extends JPanel implements Scrollable
{
ScrollablePanel()
{
setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
}

@Override
public Dimension getPreferredScrollableViewportSize()
{
return getPreferredSize();
}

@Override
public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation, int direction)
{
return 16;
}

@Override
public int getScrollableBlockIncrement(Rectangle visibleRect, int orientation, int direction)
{
return visibleRect.height;
}

@Override
public boolean getScrollableTracksViewportWidth()
{
return true;
}

@Override
public boolean getScrollableTracksViewportHeight()
{
return false;
}
}

private static class ConsistencyIndicator extends JPanel
{
private static final int MARKER_SIZE = 8;
Expand Down
Loading