FRoundedPanel consolidated into FPanel.

FPanels now support background textures and foreground images.
FPanels now have a stretch foreground image option.
FPanels now have optional hover and select behavior.
Slight performance improvement over previous FPanel versions (paintComponent trimmed down).
This commit is contained in:
Doublestrike
2012-02-11 08:47:43 +00:00
parent d0a04b224d
commit 5d18d21409
20 changed files with 359 additions and 583 deletions

View File

@@ -131,8 +131,8 @@ public final class CardPicturePanel extends JPanel implements CardContainer {
- i.top - i.bottom);
}
if ((this.card != null) && (image == null)) {
image = ImageCache.getImage(this.card, this.getWidth() - i.left - i.right, this.getHeight() - i.top
- i.bottom);
image = ImageCache.getImage(this.card, this.getWidth() - i.left - i.right - 2, this.getHeight() - i.top
- i.bottom - 2);
}
if (image != this.currentImange) {

View File

@@ -30,7 +30,9 @@ public class BazaarTopLevel extends FPanel {
this.pnlSingleStall = new ViewStall(this);
// Component styling
this.setBGTexture(FSkin.getIcon(FSkin.Backgrounds.BG_TEXTURE));
this.setCornerDiameter(0);
this.setBorderToggle(false);
this.setBackgroundTexture(FSkin.getIcon(FSkin.Backgrounds.BG_TEXTURE));
this.setLayout(new MigLayout("insets 0, gap 0"));
pnlAllStalls.setOpaque(false);
pnlAllStalls.setLayout(new MigLayout("insets 0, gap 0, wrap, align center"));

View File

@@ -10,13 +10,13 @@ import forge.Command;
import forge.quest.data.bazaar.QuestStallPurchasable;
import forge.view.GuiTopLevel;
import forge.view.toolbox.FLabel;
import forge.view.toolbox.FRoundedPanel;
import forge.view.toolbox.FPanel;
import forge.view.toolbox.FSkin;
import forge.view.toolbox.FTextArea;
/** An update-able panel instance representing a single item. */
@SuppressWarnings("serial")
public class ViewItem extends FRoundedPanel {
public class ViewItem extends FPanel {
private final FLabel lblIcon, lblName, lblPrice, btnPurchase;
private final FTextArea tarDesc;
private QuestStallPurchasable item;

View File

@@ -39,7 +39,6 @@ import forge.properties.ForgePreferences;
import forge.properties.ForgePreferences.FPref;
import forge.view.toolbox.FButton;
import forge.view.toolbox.FPanel;
import forge.view.toolbox.FRoundedPanel;
import forge.view.toolbox.FSkin;
/**
@@ -79,8 +78,9 @@ public class HomeTopLevel extends FPanel {
settings = new ViewSettings(this);
utilities = new ViewUtilities(this);
this.setOpaque(false);
this.setBGTexture(FSkin.getIcon(FSkin.Backgrounds.BG_TEXTURE));
this.setCornerDiameter(0);
this.setBorderToggle(false);
this.setBackgroundTexture(FSkin.getIcon(FSkin.Backgrounds.BG_TEXTURE));
this.setLayout(null);
this.addComponentListener(new ComponentAdapter() {
@Override
@@ -98,12 +98,10 @@ public class HomeTopLevel extends FPanel {
}
});
pnlMenu = new FRoundedPanel();
pnlMenu = new FPanel();
pnlMenu.setLayout(new MigLayout("insets 0, gap 0, wrap"));
pnlMenu.setBackground(FSkin.getColor(FSkin.Colors.CLR_THEME));
pnlContent = new FRoundedPanel();
pnlContent.setBackground(FSkin.getColor(FSkin.Colors.CLR_THEME));
pnlContent = new FPanel();
pnlContent.setLayout(new MigLayout("insets 0, gap 0"));
btnConstructed = new FButton();

View File

@@ -1,8 +1,6 @@
package forge.view.home;
import java.awt.Color;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.File;
import java.util.List;
@@ -20,6 +18,7 @@ import javax.swing.border.MatteBorder;
import net.miginfocom.swing.MigLayout;
import forge.AllZone;
import forge.Command;
import forge.control.home.ControlQuest;
import forge.game.GameType;
import forge.properties.ForgeProps;
@@ -30,9 +29,9 @@ import forge.quest.data.QuestEvent;
import forge.view.toolbox.DeckLister;
import forge.view.toolbox.FCheckBox;
import forge.view.toolbox.FLabel;
import forge.view.toolbox.FPanel;
import forge.view.toolbox.FProgressBar;
import forge.view.toolbox.FRadioButton;
import forge.view.toolbox.FRoundedPanel;
import forge.view.toolbox.FScrollPane;
import forge.view.toolbox.FSkin;
import forge.view.toolbox.FTextArea;
@@ -93,7 +92,7 @@ public class ViewQuest extends JScrollPane {
tabPreferences = new SubTab("Preferences");
pnlTabber = new JPanel();
pnlTitle = new FRoundedPanel();
pnlTitle = new FPanel();
pnlStats = new JPanel();
pnlDuels = new JPanel();
pnlChallenges = new JPanel();
@@ -206,7 +205,6 @@ public class ViewQuest extends JScrollPane {
private void populateTitle() {
pnlTitle.setLayout(new MigLayout("insets 0, gap 0, align center"));
pnlTitle.setBackground(FSkin.getColor(FSkin.Colors.CLR_THEME2));
((FRoundedPanel) pnlTitle).setBorderColor(clrBorders);
pnlTitle.add(lblTitle, "w 78%!, h 80%!, gap 0 0 15%! 15%!");
}
@@ -261,9 +259,8 @@ public class ViewQuest extends JScrollPane {
/** Layout permanent parts of quest load panel. */
private void populateLoadQuest() {
// New quest notes
final FRoundedPanel pnl = new FRoundedPanel();
final FPanel pnl = new FPanel();
pnl.setLayout(new MigLayout("insets 0, align center"));
pnl.setBorderColor(clrBorders);
pnl.setBackground(FSkin.getColor(FSkin.Colors.CLR_THEME2));
pnl.add(new FLabel.Builder().text("Load a previous Quest").build(), "h 95%!, gap 0 0 2.5% 0");
@@ -286,9 +283,8 @@ public class ViewQuest extends JScrollPane {
/** Layout permanent parts of new quests panel. */
private void populateNewQuest() {
// New quest notes
final FRoundedPanel pnl1 = new FRoundedPanel();
final FPanel pnl1 = new FPanel();
pnl1.setLayout(new MigLayout("insets 0, align center"));
pnl1.setBorderColor(clrBorders);
pnl1.setBackground(FSkin.getColor(FSkin.Colors.CLR_THEME2));
pnl1.add(new FLabel.Builder().text("Start a new quest").build(), "h 95%!, gap 0 0 2.5% 0");
@@ -438,7 +434,7 @@ public class ViewQuest extends JScrollPane {
// Select first event.
selectedOpponent = (SelectablePanel) pnlDuels.getComponent(0);
selectedOpponent.setBackground(FSkin.getColor(FSkin.Colors.CLR_ACTIVE));
selectedOpponent.setSelected(true);
}
pnlStats.setVisible(true);
@@ -467,7 +463,7 @@ public class ViewQuest extends JScrollPane {
if (pnlChallenges.getComponentCount() > 0) {
pnlStart.setVisible(true);
selectedOpponent = (SelectablePanel) pnlChallenges.getComponent(0);
selectedOpponent.setBackground(FSkin.getColor(FSkin.Colors.CLR_ACTIVE));
selectedOpponent.setSelected(true);
}
SwingUtilities.invokeLater(new Runnable() {
@@ -528,21 +524,26 @@ public class ViewQuest extends JScrollPane {
}
/** Selectable panels for duels and challenges. */
public class SelectablePanel extends FRoundedPanel {
public class SelectablePanel extends FPanel {
private QuestEvent event;
private Color clrDefault, clrHover, clrSelected;
/** @param e0   QuestEvent */
public SelectablePanel(QuestEvent e0) {
super();
this.clrSelected = FSkin.getColor(FSkin.Colors.CLR_ACTIVE);
this.clrDefault = FSkin.getColor(FSkin.Colors.CLR_INACTIVE);
this.clrHover = FSkin.getColor(FSkin.Colors.CLR_HOVER);
this.event = e0;
this.setBackground(clrDefault);
this.setSelectable(true);
this.setHoverable(true);
this.setLayout(new MigLayout("insets 0, gap 0"));
this.setCommand(new Command() {
@Override
public void execute() {
if (selectedOpponent != null) { selectedOpponent.setSelected(false); }
selectedOpponent = ViewQuest.SelectablePanel.this;
}
});
// Icon
final File base = ForgeProps.getFile(NewConstants.IMAGE_ICON);
File file = new File(base, event.getIconFilename());
@@ -555,34 +556,6 @@ public class ViewQuest extends JScrollPane {
}
this.add(lblIcon, "h 60px!, w 60px!, gap 10px 10px 10px 0, span 1 2");
this.addMouseListener(new MouseAdapter() {
@Override
public void mouseReleased(MouseEvent e) {
SelectablePanel src = (SelectablePanel) e.getSource();
if (selectedOpponent != null) {
selectedOpponent.setBackground(clrDefault);
}
selectedOpponent = src;
src.setBackground(clrSelected);
}
@Override
public void mouseEntered(MouseEvent e) {
if (selectedOpponent != e.getSource()) {
setBackground(clrHover);
}
}
@Override
public void mouseExited(MouseEvent e) {
if (selectedOpponent != e.getSource()) {
setBackground(clrDefault);
}
}
});
// Name
final FLabel lblName = new FLabel.Builder()
.text(event.getTitle() + ": " + event.getDifficulty()).hoverable(false).build();

View File

@@ -31,7 +31,6 @@ import javax.swing.JPanel;
import javax.swing.JTextArea;
import net.miginfocom.swing.MigLayout;
import forge.AllZone;
import forge.control.ControlMatchUI;
import forge.control.match.ControlDetail;
@@ -96,8 +95,10 @@ public class MatchTopLevel extends FPanel {
// Set properties
this.setOpaque(false);
this.setBGTexture(FSkin.getIcon(FSkin.Backgrounds.BG_TEXTURE));
this.setBGImg(FSkin.getIcon(FSkin.Backgrounds.BG_MATCH));
this.setBackgroundTexture(FSkin.getIcon(FSkin.Backgrounds.BG_TEXTURE));
this.setForegroundImage(FSkin.getIcon(FSkin.Backgrounds.BG_MATCH));
this.setCornerDiameter(0);
this.setBorderToggle(false);
this.setLayout(null);
b = (int) Math.ceil(BOUNDARY_THICKNESS_PX / 2);

View File

@@ -20,9 +20,10 @@ package forge.view.match;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JPanel;
import net.miginfocom.swing.MigLayout;
import forge.AllZone;
import forge.view.toolbox.FPanel;
/**
* Battlefield, assembles and contains instances of MatchPlayer. SHOULD PROBABLY
@@ -30,7 +31,7 @@ import forge.view.toolbox.FPanel;
*
*/
@SuppressWarnings("serial")
public class ViewBattlefield extends FPanel {
public class ViewBattlefield extends JPanel {
private final List<ViewField> fields;
/**

View File

@@ -24,7 +24,7 @@ import java.awt.event.ComponentEvent;
import net.miginfocom.swing.MigLayout;
import forge.control.match.ControlDetail;
import forge.gui.game.CardDetailPanel;
import forge.view.toolbox.FRoundedPanel;
import forge.view.toolbox.FPanel;
import forge.view.toolbox.FSkin;
/**
@@ -32,7 +32,7 @@ import forge.view.toolbox.FSkin;
*
*/
@SuppressWarnings("serial")
public class ViewDetail extends FRoundedPanel {
public class ViewDetail extends FPanel {
private ControlDetail control;
private CardDetailPanel pnlDetail;

View File

@@ -37,7 +37,7 @@ import forge.AllZone;
import forge.control.match.ControlDock;
import forge.view.toolbox.FButton;
import forge.view.toolbox.FOverlay;
import forge.view.toolbox.FRoundedPanel;
import forge.view.toolbox.FPanel;
import forge.view.toolbox.FSkin;
/**
@@ -45,7 +45,7 @@ import forge.view.toolbox.FSkin;
*
*/
@SuppressWarnings("serial")
public class ViewDock extends FRoundedPanel {
public class ViewDock extends FPanel {
private final ControlDock control;
private final Action actClose;
@@ -56,7 +56,6 @@ public class ViewDock extends FRoundedPanel {
public ViewDock() {
super();
this.setToolTipText("Shortcut Button Dock");
this.setBackground(FSkin.getColor(FSkin.Colors.CLR_THEME));
//this.setLayout(new MigLayout("insets 0, gap 0, ay center, ax center"));
// Mig layout does not support wrapping!

View File

@@ -49,7 +49,7 @@ import forge.properties.ForgeProps;
import forge.properties.NewConstants;
import forge.view.GuiTopLevel;
import forge.view.toolbox.FLabel;
import forge.view.toolbox.FRoundedPanel;
import forge.view.toolbox.FPanel;
import forge.view.toolbox.FSkin;
import forge.view.toolbox.FSkin.SkinProp;
@@ -58,7 +58,7 @@ import forge.view.toolbox.FSkin.SkinProp;
*
*/
@SuppressWarnings("serial")
public class ViewField extends FRoundedPanel {
public class ViewField extends FPanel {
private final ControlField control;
private final PlayArea tabletop;
@@ -85,11 +85,8 @@ public class ViewField extends FRoundedPanel {
*/
public ViewField(final Player player) {
super();
this.setOpaque(false);
this.setLayout(new MigLayout("insets 0, gap 0"));
this.setCornerRadius(5);
this.setToolTipText(player.getName() + " Gameboard");
this.setBackground(FSkin.getColor(FSkin.Colors.CLR_THEME));
this.inactiveBorder = new LineBorder(new Color(0, 0, 0, 0), 1);
this.hoverBorder = new LineBorder(FSkin.getColor(FSkin.Colors.CLR_BORDERS), 1);

View File

@@ -22,15 +22,14 @@ import javax.swing.JScrollPane;
import net.miginfocom.swing.MigLayout;
import arcane.ui.HandArea;
import forge.control.match.ControlHand;
import forge.view.toolbox.FRoundedPanel;
import forge.view.toolbox.FSkin;
import forge.view.toolbox.FPanel;
/**
* VIEW - Swing components for user hand.
*
*/
@SuppressWarnings("serial")
public class ViewHand extends FRoundedPanel {
public class ViewHand extends FPanel {
private ControlHand control;
private HandArea hand;
private MatchTopLevel topLevel;
@@ -43,7 +42,6 @@ public class ViewHand extends FRoundedPanel {
public ViewHand(MatchTopLevel v0) {
final JScrollPane scroller = new JScrollPane();
ViewHand.this.hand = new HandArea(scroller);
ViewHand.this.setBackground(FSkin.getColor(FSkin.Colors.CLR_THEME));
topLevel = v0;
scroller.setViewportView(ViewHand.this.hand);

View File

@@ -33,7 +33,7 @@ import javax.swing.border.MatteBorder;
import net.miginfocom.swing.MigLayout;
import forge.control.match.ControlInput;
import forge.view.toolbox.FButton;
import forge.view.toolbox.FRoundedPanel;
import forge.view.toolbox.FPanel;
import forge.view.toolbox.FSkin;
/**
@@ -41,7 +41,7 @@ import forge.view.toolbox.FSkin;
*
*/
@SuppressWarnings("serial")
public class ViewInput extends FRoundedPanel {
public class ViewInput extends FPanel {
private final ControlInput control;
private final JButton btnOK, btnCancel;
private final JTextArea tarMessage;
@@ -57,8 +57,6 @@ public class ViewInput extends FRoundedPanel {
public ViewInput() {
super();
this.setToolTipText("Input Area");
this.setBackground(FSkin.getColor(FSkin.Colors.CLR_THEME));
this.setForeground(FSkin.getColor(FSkin.Colors.CLR_TEXT));
this.setLayout(new MigLayout("wrap 2, fill, insets 0, gap 0"));
// Cancel button
@@ -156,6 +154,7 @@ public class ViewInput extends FRoundedPanel {
remindIsRunning = false;
timer1.stop();
}
repaint();
}
};

View File

@@ -20,15 +20,14 @@ package forge.view.match;
import net.miginfocom.swing.MigLayout;
import forge.control.match.ControlPicture;
import forge.gui.game.CardPicturePanel;
import forge.view.toolbox.FRoundedPanel;
import forge.view.toolbox.FSkin;
import forge.view.toolbox.FPanel;
/**
* TODO: Write javadoc for this type.
*
*/
@SuppressWarnings("serial")
public class ViewPicture extends FRoundedPanel {
public class ViewPicture extends FPanel {
private ControlPicture control;
private CardPicturePanel pnlPicture;
@@ -41,7 +40,6 @@ public class ViewPicture extends FRoundedPanel {
pnlPicture = new CardPicturePanel(null);
pnlPicture.setOpaque(false);
this.setBackground(FSkin.getColor(FSkin.Colors.CLR_THEME));
this.setLayout(new MigLayout("insets 0, gap 0, center"));
add(pnlPicture, "w 100%!, h 100%!");

View File

@@ -61,8 +61,6 @@ import forge.gui.MultiLineLabelUI;
import forge.properties.ForgePreferences.FPref;
import forge.properties.NewConstants;
import forge.view.GuiTopLevel;
import forge.view.toolbox.FPanel;
import forge.view.toolbox.FRoundedPanel;
import forge.view.toolbox.FSkin;
import forge.view.toolbox.FVerticalTabPanel;
@@ -73,7 +71,7 @@ import forge.view.toolbox.FVerticalTabPanel;
*
*/
@SuppressWarnings("serial")
public class ViewTabber extends FRoundedPanel {
public class ViewTabber extends JPanel {
private final List<JPanel> panelList;
private Map<Player, JLabel[]> infoLBLs;
private JLabel stormLabel;
@@ -84,7 +82,7 @@ public class ViewTabber extends FRoundedPanel {
private final ControlTabber control;
private TriggerReactionMenu triggerMenu;
private final FPanel pnlStack, pnlCombat, pnlConsole, pnlPlayers, pnlDev;
private final JPanel pnlStack, pnlCombat, pnlConsole, pnlPlayers, pnlDev;
private DevLabel lblMilling, lblGenerateMana, lblSetupGame, lblTutor,
lblCounterPermanent, lblTapPermanent, lblUntapPermanent, lblUnlimitedLands, lblSetLife;
@@ -100,6 +98,7 @@ public class ViewTabber extends FRoundedPanel {
this.hoverColor = FSkin.getColor(FSkin.Colors.CLR_HOVER);
this.activeColor = FSkin.getColor(FSkin.Colors.CLR_ACTIVE);
this.inactiveColor = FSkin.getColor(FSkin.Colors.CLR_INACTIVE);
this.setOpaque(false);
// Assemble card pic viewer
this.panelList = new ArrayList<JPanel>();
@@ -112,35 +111,35 @@ public class ViewTabber extends FRoundedPanel {
// Trigger Context Menu creation
this.triggerMenu = new TriggerReactionMenu();
this.pnlStack = new FPanel();
this.pnlStack = new JPanel();
this.pnlStack.setName("Stack");
this.pnlStack.setOpaque(false);
this.pnlStack.setLayout(new MigLayout(constraints));
this.pnlStack.setToolTipText("View Stack");
this.panelList.add(this.pnlStack);
this.pnlCombat = new FPanel();
this.pnlCombat = new JPanel();
this.pnlCombat.setName("Combat");
this.pnlCombat.setOpaque(false);
this.pnlCombat.setLayout(new MigLayout(constraints));
this.pnlCombat.setToolTipText("View Combat");
this.panelList.add(this.pnlCombat);
this.pnlConsole = new FPanel();
this.pnlConsole = new JPanel();
this.pnlConsole.setName("Log");
this.pnlConsole.setOpaque(false);
this.pnlConsole.setLayout(new MigLayout(constraints));
this.pnlConsole.setToolTipText("View Console");
this.panelList.add(this.pnlConsole);
this.pnlPlayers = new FPanel();
this.pnlPlayers = new JPanel();
this.pnlPlayers.setName("Players");
this.pnlPlayers.setOpaque(false);
this.pnlPlayers.setLayout(new MigLayout(constraints));
this.pnlPlayers.setToolTipText("Player List");
this.panelList.add(this.pnlPlayers);
this.pnlDev = new FPanel();
this.pnlDev = new JPanel();
this.pnlDev.setName("Dev");
this.pnlDev.setOpaque(false);
this.pnlDev.setLayout(new MigLayout(constraints));
@@ -455,45 +454,45 @@ public class ViewTabber extends FRoundedPanel {
/**
* Gets the pnl stack.
*
* @return FPanel
* @return {@link javax.swing.JPanel}
*/
public FPanel getPnlStack() {
public JPanel getPnlStack() {
return this.pnlStack;
}
/**
* Gets the pnl combat.
*
* @return FPanel
* @return {@link javax.swing.JPanel}
*/
public FPanel getPnlCombat() {
public JPanel getPnlCombat() {
return this.pnlCombat;
}
/**
* Gets the pnl console.
*
* @return FPanel
* @return {@link javax.swing.JPanel}
*/
public FPanel getPnlConsole() {
public JPanel getPnlConsole() {
return this.pnlConsole;
}
/**
* Gets the pnl players.
*
* @return FPanel
* @return {@link javax.swing.JPanel}
*/
public FPanel getPnlPlayers() {
public JPanel getPnlPlayers() {
return this.pnlPlayers;
}
/**
* Gets the pnl dev.
*
* @return FPanel
* @return {@link javax.swing.JPanel}
*/
public FPanel getPnlDev() {
public JPanel getPnlDev() {
return this.pnlDev;
}

View File

@@ -36,7 +36,7 @@ import forge.Command;
@SuppressWarnings("serial")
public class FLabel extends JLabel {
/**
* Uses the amazing Builder pattern to facilitate/encourage inline styling.
* Uses the Builder pattern to facilitate/encourage inline styling.
* Credit to Effective Java 2 (Joshua Bloch), a fantastic book.
* Methods in builder can be chained. To declare:
* <code>new FLabel.Builder().method1(foo).method2(bar).method3(baz)...</code>
@@ -133,7 +133,7 @@ public class FLabel extends JLabel {
}
//========== Constructors
/** Must have protected constructor to allow subclassing. */
/** Must have protected constructor to allow Builder to subclass. */
protected FLabel() { }
// Call this using FLabel.Builder()...
@@ -173,6 +173,7 @@ public class FLabel extends JLabel {
this.addComponentListener(cadResize);
}
//========== Variable initialization
// Final inits
private final Color clrText = FSkin.getColor(FSkin.Colors.CLR_TEXT);
private final Color clrBorders = FSkin.getColor(FSkin.Colors.CLR_BORDERS);
@@ -241,6 +242,7 @@ public class FLabel extends JLabel {
}
};
//========== Methods
/** @param b0 &emsp; boolean */
// Must be public.
public void setHoverable(boolean b0) {
@@ -328,7 +330,7 @@ public class FLabel extends JLabel {
}
@Override
public void paintComponent(Graphics g) {
protected void paintComponent(Graphics g) {
g2d = (Graphics2D) g.create();
w = getWidth();
h = getHeight();

View File

@@ -17,47 +17,176 @@
*/
package forge.view.toolbox;
import java.awt.Dimension;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.LayoutManager;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.Area;
import java.awt.geom.RoundRectangle2D;
import javax.swing.ImageIcon;
import javax.swing.JPanel;
import javax.swing.border.Border;
/**
* <p>
* FPanel.
* </p>
* The core JPanel used throughout the Forge project. Allows tiled texture
* images and single background images, using setBGTexture() and setBGImage()
* respectively.
*
import forge.Command;
/**
* Core panel used in UI.
* <br><br>
* Adjustable features of FPanel:<br>
* - Hoverable<br>
* - Selectable<br>
* - Tiled background texture<br>
* - Foreground picture, option for stretch to fit<br>
* - Rounded corners<br>
* - Border toggle<br>
*/
@SuppressWarnings("serial")
public class FPanel extends JPanel {
private Image bgTexture, bgImg = null;
// Panel Width, panel Height, Image Width, Image Height, Image Aspect Ratio
private double w, h, iw, ih, iar, x, y = 0;
//========== Variable initialization
// Defaults for adjustable values
private boolean selectable = false;
private boolean hoverable = false;
private boolean foregroundStretch = false;
private Image foregroundImage = null;
private Image backgroundTexture = null;
private Color borderColor = FSkin.getColor(FSkin.Colors.CLR_BORDERS);
private boolean borderToggle = true;
private int cornerDiameter = 20;
/**
* Instantiates a new f panel.
*/
// Mouse handling
private boolean selected, hovered;
private Command cmdClick;
// Width/height of panel, bg img, scaled bg img, texture img. Coords.
private int pw, ph, iw, ih, sw, sh, tw, th, x, y;
// Image aspect ratio (width / height)
private double iar;
// Graphics clone to avoid clobbering original
private Graphics2D g2d;
// Clip rounded corner shape
private Area clip;
private BasicStroke borderStroke = new BasicStroke(2.0f);
/** Core panel used in UI. See class javadoc for more details. */
public FPanel() {
super();
// Opacity must be removed for proper rounded corner drawing
this.setOpaque(false);
// Background will follow skin theme.
this.setBackground(FSkin.getColor(FSkin.Colors.CLR_THEME));
}
/**
* Instantiates a new f panel.
*
* @param lm
* the lm
*/
public FPanel(final LayoutManager lm) {
this();
this.setLayout(lm);
// Mouse event handler
private final MouseAdapter madEvents = new MouseAdapter() {
@Override
public void mouseEntered(MouseEvent e) { hovered = true; repaint(); }
@Override
public void mouseExited(MouseEvent e) { hovered = false; repaint(); }
@Override
public void mouseClicked(MouseEvent e) {
if (cmdClick != null) { cmdClick.execute(); }
if (!selectable) { return; }
if (selected) { setSelected(false); }
else { setSelected(true); }
}
};
//========== Mutators
/**@param i0 &emsp; int */
public void setCornerDiameter(int i0) {
if (i0 < 0) { i0 = 0; }
this.cornerDiameter = i0;
}
/** @param c0 &emsp; {@link forge.Command} on click */
public void setCommand(Command c0) {
this.cmdClick = c0;
}
/** @return {@link forge.Command} */
public Command getCommand() {
return this.cmdClick;
}
/** @param b0 &emsp; boolean */
public void setHoverable(boolean b0) {
hoverable = b0;
this.confirmDrawEfficiency();
if (!b0) { this.removeMouseListener(madEvents); }
else { this.addMouseListener(madEvents); }
}
/** @param b0 &emsp; boolean */
public void setSelectable(boolean b0) {
this.selectable = b0;
this.confirmDrawEfficiency();
}
/** @param b0 &emsp; boolean */
public void setSelected(boolean b0) {
selected = b0;
if (b0) { this.setBackground(FSkin.getColor(FSkin.Colors.CLR_ACTIVE)); }
else { this.setBackground(FSkin.getColor(FSkin.Colors.CLR_INACTIVE)); }
repaint();
}
/** @param i0 &emsp; {@link java.awt.Image} */
public void setForegroundImage(Image i0) {
if (i0 == null) { return; }
this.foregroundImage = i0;
this.iw = i0.getWidth(null);
this.ih = i0.getHeight(null);
this.iar = (double) iw / (double) ih;
}
/** @param i0 &emsp; {@link javax.swing.ImageIcon} */
public void setForegroundImage(ImageIcon i0) {
setForegroundImage(i0.getImage());
}
/** @param b0 &emsp; boolean, stretch the foreground to fit */
public void setForegroundStretch(final boolean b0) {
this.foregroundStretch = b0;
}
/** @param i0 &emsp; {@link java.awt.Image} */
public void setBackgroundTexture(Image i0) {
if (i0 == null) { return; }
this.backgroundTexture = i0;
this.tw = i0.getWidth(null);
this.th = i0.getHeight(null);
}
/** @param i0 &emsp; {@link javax.swing.ImageIcon} */
public void setBackgroundTexture(ImageIcon i0) {
setBackgroundTexture(i0.getImage());
}
/** @param b0 &emsp; boolean */
public void setBorderToggle(final boolean b0) {
this.borderToggle = b0;
}
/** @param c0 &emsp; {@link java.awt.Color} */
public void setBorderColor(final Color c0) {
this.borderColor = c0;
}
@Override
public void setBorder(Border b0) { }
@Override
public void setOpaque(boolean b0) { super.setOpaque(false); }
/*
* (non-Javadoc)
*
@@ -65,117 +194,134 @@ public class FPanel extends JPanel {
*/
@Override
protected void paintComponent(final Graphics g) {
this.w = this.getWidth();
this.h = this.getHeight();
pw = this.getWidth();
ph = this.getHeight();
g2d = (Graphics2D) g.create();
// Draw background texture
if (this.bgTexture != null) {
this.iw = this.bgTexture.getWidth(null);
this.ih = this.bgTexture.getHeight(null);
this.x = 0;
// Set clip for rounded area
if (cornerDiameter > 0) {
clip = new Area(new RoundRectangle2D.Float(0, 0, pw, ph, cornerDiameter, cornerDiameter));
g2d.setClip(clip);
}
// Draw background as required
if (foregroundStretch && foregroundImage != null) {
drawForegroundStretched(g2d);
}
else if (this.backgroundTexture != null) {
drawBackgroundTexture(g2d);
}
else {
drawBackgroundColor(g2d);
}
// Draw foreground as required
if (!foregroundStretch && foregroundImage != null) {
drawForegroundScaled(g2d);
}
if (borderToggle) {
drawBorder(g2d);
}
// Clear memory
if (clip != null) { clip.reset(); }
g2d.dispose();
}
//========== Special draw methods
private void drawBackgroundColor(final Graphics g0) {
// Color background as appropriate
if (selected) { g0.setColor(FSkin.getColor(FSkin.Colors.CLR_ACTIVE)); }
else if (hovered) { g0.setColor(FSkin.getColor(FSkin.Colors.CLR_HOVER)); }
else if (selectable) { g0.setColor(FSkin.getColor(FSkin.Colors.CLR_INACTIVE)); }
else { g0.setColor(getBackground()); }
// Parent must be drawn onto clipped object.
g0.fillRoundRect(0, 0, pw, ph, cornerDiameter, cornerDiameter);
}
private void drawBackgroundTexture(final Graphics g0) {
this.x = 0;
this.y = 0;
while (this.x < this.pw) {
while (this.y < this.ph) {
g0.drawImage(this.backgroundTexture, (int) this.x, (int) this.y, null);
this.y += this.th;
}
this.x += this.tw;
this.y = 0;
}
this.x = 0;
}
while (this.x < this.w) {
while (this.y < this.h) {
g.drawImage(this.bgTexture, (int) this.x, (int) this.y, null);
this.y += this.ih;
}
this.x += this.iw;
this.y = 0;
}
this.x = 0;
private void drawForegroundScaled(final Graphics g0) {
// Scaling 1: First dimension larger than panel
if (iw >= pw) { // Image is wider than panel? Shrink to width.
sw = pw;
sh = (int) (sw / iar);
}
else if (ih >= ph) { // Image is taller than panel? Shrink to height.
sh = ph;
sw = (int) (sh * iar);
}
else { // Image is smaller than panel? No scaling.
sw = iw;
sh = ih;
}
// Draw background image
if (this.bgImg != null) {
this.iw = this.bgImg.getWidth(null); // Image Width
this.ih = this.bgImg.getHeight(null); // Image Height
this.iar = this.iw / this.ih; // Image Aspect Ratio
// Image is smaller than panel:
if ((this.w > this.iw) && (this.h > this.ih)) {
g.drawImage(this.bgImg, (int) (this.w - this.iw) / 2, (int) (this.h - this.ih) / 2, (int) this.iw,
(int) this.ih, null);
}
// Image is larger than panel, and tall:
else if (this.iar < 1) {
g.drawImage(this.bgImg, (int) ((this.w - (this.h * this.iar)) / 2), 0,
(int) ((this.w + (this.h * this.iar)) / 2), (int) this.h, 0, 0, (int) this.iw, (int) this.ih,
null);
}
// Image is larger than panel, and wide:
else if (this.iar > 1) {
g.drawImage(this.bgImg, 0, (int) ((this.h - (this.w / this.iar)) / 2), (int) this.w,
(int) ((this.h + (this.w / this.iar)) / 2), 0, 0, (int) this.iw, (int) this.ih, null);
}
// Scaling step 2: Second dimension larger than panel
if (sh > ph) { // Scaled image still taller than panel?
sh = ph;
sw = (int) (sh * iar);
}
else if (sw > pw) { // Scaled image still wider than panel?
sw = pw;
sh = (int) (sw / iar);
}
super.paintComponent(g);
// Scaling step 3: Center image in panel
x = (int) ((pw - sw) / 2);
y = (int) ((ph - sh) / 2);
g0.drawImage(foregroundImage, x, y, sw + x, sh + y, 0, 0, iw, ih, null);
}
/**
* An FPanel can have a tiled texture and an image. The texture will be
* drawn first. If a background image has been set, it will be drawn on top
* of the texture, centered and scaled proportional to its aspect ratio.
*
* @param i0
* &emsp; ImageIcon
*/
public void setBGImg(final ImageIcon i0) {
this.bgImg = i0.getImage();
if (this.bgImg != null) {
this.setOpaque(false);
private void drawForegroundStretched(final Graphics g0) {
g0.drawImage(foregroundImage, 0, 0, pw, ph, 0, 0, iw, ih, null);
}
private void drawBorder(final Graphics2D g0) {
g0.setColor(borderColor);
g0.setStroke(borderStroke);
g0.drawRoundRect(0, 0, pw, ph, cornerDiameter, cornerDiameter);
}
/** Improves performance by checking to see if any graphics will cancel
* each other out, so unnecessary out-of-sight graphics will not stack up. */
private void confirmDrawEfficiency() {
if (hoverable && foregroundStretch) {
throw new IllegalArgumentException("\nAn FPanel may not be simultaneously "
+ "hoverable and have a stretched foreground image.\n"
+ "Please adjust the panel's declaration to use one or the other.");
}
}
/**
* An FPanel can have a tiled texture and an image. The texture will be
* drawn first. If a background image has been set, it will be drawn on top
* of the texture, centered and scaled proportional to its aspect ratio.
*
* @param i0
* &emsp; ImageIcon
*/
public void setBGTexture(final ImageIcon i0) {
this.bgTexture = i0.getImage();
if (this.bgTexture != null) {
this.setOpaque(false);
if (hoverable && backgroundTexture != null) {
throw new IllegalArgumentException("\nAn FPanel may not be simultaneously "
+ "hoverable and have a background texture.\n"
+ "Please adjust the panel's declaration to use one or the other.");
}
}
/**
* Sets the preferred size.
*
* @param w
* the w
* @param h
* the h
*/
public void setPreferredSize(final int w, final int h) {
this.setPreferredSize(new Dimension(w, h));
}
if (selectable && foregroundStretch) {
throw new IllegalArgumentException("\nAn FPanel may not be simultaneously "
+ "selectable and have a stretched foreground image.\n"
+ "Please adjust the panel's declaration to use one or the other.");
}
/**
* Sets the maximum size.
*
* @param w
* the w
* @param h
* the h
*/
public void setMaximumSize(final int w, final int h) {
this.setMaximumSize(new Dimension(w, h));
}
/**
* Sets the minimum size.
*
* @param w
* the w
* @param h
* the h
*/
public void setMinimumSize(final int w, final int h) {
this.setMinimumSize(new Dimension(w, h));
if (selectable && backgroundTexture != null) {
throw new IllegalArgumentException("\nAn FPanel may not be simultaneously "
+ "selectable and have a background texture.\n"
+ "Please adjust the panel's declaration to use one or the other.");
}
}
}

View File

@@ -1,332 +0,0 @@
/*
* Forge: Play Magic: the Gathering.
* Copyright (C) 2011 Forge Team
*
* 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 3 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.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package forge.view.toolbox;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.LayoutManager;
import java.awt.RenderingHints;
import javax.swing.JPanel;
/**
* <p>
* FRoundedPanel.
* </p>
* A subclass of JPanel with any of four corners rounded, drop shadow, and 1px
* line border.
*
* Limitations: Cannot tile background image, cannot set border width.
*
*/
@SuppressWarnings("serial")
public class FRoundedPanel extends JPanel {
private boolean[] borders = { true, true, true, true };
private boolean[] corners = { true, true, true, true }; // NW, SW, SE, NE
private Color shadowColor = new Color(150, 150, 150, 150);
private Color borderColor = FSkin.getColor(FSkin.Colors.CLR_BORDERS);
private int shadowOffset = 5;
private int cornerRadius = 10;
private boolean showShadow = false;
/**
* <p>
* FRoundedPanel.
* </p>
*
* Constructor, null layout manager.
*/
public FRoundedPanel() {
super();
this.setOpaque(false);
}
/**
* <p>
* FRoundedPanel.
* </p>
*
* Constructor.
*
* @param lm
* the lm
*/
public FRoundedPanel(final LayoutManager lm) {
this();
this.setLayout(lm);
}
/**
* paintComponent is the guts of FRoundedPanel. It paints the borders and
* rounded corners determined by the conditional arrays <b>borders[ ]</b>
* and <b>corners[ ]</b>.
*
* @param g
* &emsp; Graphics obj
*/
@Override
protected void paintComponent(final Graphics g) {
super.paintComponent(g);
final int w = this.getWidth();
final int h = this.getHeight();
int so = this.shadowOffset;
final int r = this.cornerRadius;
final Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
if (this.showShadow) {
// Mid, left, right rectangles: shadow
g2d.setColor(this.shadowColor);
g2d.fillRect(r + so, so, w - (2 * r) - so, h - so);
g2d.fillRect(so, r + so, r, h - (2 * r) - so);
g2d.fillRect(w - r, r + so, r, h - (2 * r) - so);
// Corners: shadow
// NW
if (this.corners[0]) {
g2d.fillArc(so, so, 2 * r, 2 * r, 90, 90);
} else {
g2d.fillRect(so, so, r, r);
}
// SW
if (this.corners[1]) {
g2d.fillArc(so, h - (2 * r), 2 * r, 2 * r, 180, 90);
} else {
g2d.fillRect(so, h - r, r, r);
}
// SE
if (this.corners[2]) {
g2d.fillArc(w - (2 * r), h - (2 * r), 2 * r, 2 * r, 270, 90);
} else {
g2d.fillRect(w - r, h - r, r, r);
}
// NE
if (this.corners[3]) {
g2d.fillArc(w - (2 * r), so, 2 * r, 2 * r, 0, 90);
} else {
g2d.fillRect(w - r, so, r, r);
}
} // End if(showShadow)
else {
so = 0;
so = 0;
}
// Mid, left, right rectangles: content
g2d.setColor(this.getBackground());
g2d.fillRect(r, 0, w - (2 * r) - so, h - so);
g2d.fillRect(0, r, r, h - (2 * r) - so);
g2d.fillRect(w - r - so, r, r, h - (2 * r) - so);
// Corners: content
// NW
if (this.corners[0]) {
g2d.fillArc(0, 0, 2 * r, 2 * r, 90, 90);
} else {
g2d.fillRect(0, 0, r, r);
}
// SW
if (this.corners[1]) {
g2d.fillArc(0, h - (2 * r) - so, 2 * r, 2 * r, 180, 90);
} else {
g2d.fillRect(0, h - r - so, r, r);
}
// SE
if (this.corners[2]) {
g2d.fillArc(w - (2 * r) - so, h - (2 * r) - so, 2 * r, 2 * r, 270, 90);
} else {
g2d.fillRect(w - r - so, h - r - so, r, r);
}
// NE
if (this.corners[3]) {
g2d.fillArc(w - (2 * r) - so, 0, 2 * r, 2 * r, 0, 90);
} else {
g2d.fillRect(w - r - so, 0, r, r);
}
// Mid, left, right rectangles: border
g2d.setColor(this.borderColor);
if (this.borders[0]) {
g2d.drawLine(r, 0, w - r - so, 0);
}
if (this.borders[1]) {
g2d.drawLine(0, r, 0, h - r - so);
}
if (this.borders[2]) {
g2d.drawLine(r, h - so - 1, w - r - so, h - so - 1);
}
if (this.borders[3]) {
g2d.drawLine(w - so - 1, r, w - so - 1, h - r - so);
}
// Corners: border
// NW
if (this.corners[0]) {
g2d.drawArc(0, 0, 2 * r, 2 * r, 90, 90);
} else {
if (this.borders[0]) {
g2d.drawLine(0, 0, r, 0);
}
if (this.borders[1]) {
g2d.drawLine(0, 0, 0, r);
}
}
// SW
if (this.corners[1]) {
g2d.drawArc(0, h - (2 * r) - so, 2 * r, (2 * r) - 1, 180, 90);
} else {
if (this.borders[1]) {
g2d.drawLine(0, h - so - 1, 0, h - r - so - 1);
}
if (this.borders[2]) {
g2d.drawLine(0, h - so - 1, r, h - so - 1);
}
}
// SE
if (this.corners[2]) {
g2d.drawArc(w - (2 * r) - so, h - (2 * r) - so, (2 * r) - 1, (2 * r) - 1, 270, 90);
} else {
if (this.borders[2]) {
g2d.drawLine(w - so - 1, h - so - 1, w - r - so, h - so - 1);
}
if (this.borders[3]) {
g2d.drawLine(w - so - 1, h - so - 1, w - so - 1, h - r - so);
}
}
// NE
if (this.corners[3]) {
g2d.drawArc(w - (2 * r) - so, 0, (2 * r) - 1, (2 * r) - 1, 0, 90);
} else {
if (this.borders[0]) {
g2d.drawLine(w - so - 1, 0, w - so - r, 0);
}
if (this.borders[3]) {
g2d.drawLine(w - so - 1, 0, w - so - 1, r);
}
}
}
/**
* <p>
* setShadowColor.
* </p>
* Sets color of shadow behind rounded panel.
*
* @param c
* the new shadow color
*/
public void setShadowColor(final Color c) {
this.shadowColor = c;
}
/**
* <p>
* setBorderColor.
* </p>
* Sets color of border around rounded panel.
*
* @param c
* the new border color
*/
public void setBorderColor(final Color c) {
this.borderColor = c;
}
/**
* <p>
* setShadowOffset.
* </p>
* Sets offset of shadow from rounded panel.
*
* @param i
* the new shadow offset
*/
public void setShadowOffset(int i) {
if (i < 0) {
i = 0;
}
this.shadowOffset = i;
}
/**
* <p>
* setCornerRadius.
* </p>
* Sets radius of each corner on rounded panel.
*
* @param r0
* &emsp; int
*/
public void setCornerRadius(int r0) {
if (r0 < 0) {
r0 = 0;
}
this.cornerRadius = r0;
}
/**
* <p>
* setCorners.
* </p>
* Sets if corners should be rounded or not in the following order: NW, SW,
* SE, NE
*
* @param vals
* &emsp; boolean[4]
*/
public void setCorners(final boolean[] vals) {
if (vals.length != 4) {
throw new IllegalArgumentException("FRoundedPanel > setCorners requires an array of booleans of length 4.");
}
this.corners = vals;
}
/**
* <p>
* setBorders.
* </p>
* Sets if borders should be displayed or not following order: N, W, S, E.
* Only works for square corners, rounded corners will be shown with
* borders.
*
* @param vals
* &emsp; boolean[4]
*/
public void setBorders(final boolean[] vals) {
if (vals.length != 4) {
throw new IllegalArgumentException("FRoundedPanel > setBorders requires an array of booleans of length 4.");
}
this.borders = vals;
}
/**
* Sets the show shadow.
*
* @param b
* the new show shadow
*/
public void setShowShadow(final boolean b) {
this.showShadow = b;
}
}

View File

@@ -545,7 +545,7 @@ public enum FSkin {
* Gets an image.
*
* @param s0 &emsp; SkinProp enum
* @return Image
* @return {@link java.awt.Image}
*/
public static Image getImage(final SkinProp s0) {
return FSkin.images.get(s0);
@@ -555,7 +555,7 @@ public enum FSkin {
* Gets an icon.
*
* @param s0 &emsp; SkinProp enum
* @return ImageIcon
* @return {@link javax.swing.ImageIcon}
*/
public static ImageIcon getIcon(final SkinProp s0) {
return FSkin.icons.get(s0);
@@ -570,7 +570,7 @@ public enum FSkin {
* int new width
* @param h0
* int new height
* @return Image
* @return {@link java.awt.Image}
*/
public static Image getImage(final SkinProp s0, int w0, int h0) {
w0 = (w0 < 1) ? 1 : w0;

View File

@@ -39,7 +39,7 @@ import net.miginfocom.swing.MigLayout;
*
*/
@SuppressWarnings("serial")
public class FVerticalTabPanel extends FPanel {
public class FVerticalTabPanel extends JPanel {
private final CardLayout cards;
private final JPanel pnlContent;
private final List<VTab> allVTabs;
@@ -81,33 +81,32 @@ public class FVerticalTabPanel extends FPanel {
this.activeColor = FSkin.getColor(FSkin.Colors.CLR_ACTIVE);
this.inactiveColor = FSkin.getColor(FSkin.Colors.CLR_INACTIVE);
final int pctTabH = ((100 - 2 - 2) / size);
// Width of tabs, in percent width of container
final int pctTabW = 11;
final int pctInsetH = 3;
final int pctSpacing = 1;
// Spacing above and below each tab
final double pctSpacing = 0.5;
//
final int pctTabH = (int) ((100 - size * pctSpacing * 2) / size);
// Content panel and card layout inits
this.cards = new CardLayout();
this.pnlContent = new JPanel();
this.pnlContent.setOpaque(false);
this.pnlContent = new FPanel();
((FPanel) pnlContent).setCornerDiameter(0);
this.pnlContent.setLayout(this.cards);
// If tabs are on the left side, content panel is added
// immediately to define grid.
if (tabsOnRightSide) {
this.add(this.pnlContent, "span 1 " + (size + 2) + ", w " + (100 - pctTabW) + "%!, h 100%!");
this.add(this.pnlContent, "span 1 " + (size + 1) + ", w " + (100 - pctTabW) + "%!, h 100%!");
this.pnlContent.setBorder(new MatteBorder(0, 0, 0, 1, FSkin.getColor(FSkin.Colors.CLR_BORDERS)));
}
// Add top spacer in any case.
final JPanel topSpacer = new JPanel();
topSpacer.setOpaque(false);
this.add(topSpacer, "w " + pctTabW + "%!, h " + pctInsetH + "%!");
this.add(new JPanel(), "w 0, h 0!");
// If tabs are on right side, content panel
// must be added after spacer, which then defines the grid.
if (!tabsOnRightSide) {
this.add(this.pnlContent, "span 1 " + (size + 2) + ", w " + (100 - pctTabW) + "%!, h 100%!");
this.add(this.pnlContent, "span 1 " + (size + 1) + ", w " + (100 - pctTabW) + "%!, h 100%!");
this.pnlContent.setBorder(new MatteBorder(0, 1, 0, 0, FSkin.getColor(FSkin.Colors.CLR_BORDERS)));
}
@@ -126,16 +125,13 @@ public class FVerticalTabPanel extends FPanel {
tab.setBackground(this.inactiveColor);
}
this.add(tab, "w " + pctTabW + "%!, h " + (pctTabH - pctSpacing) + "%!, gapbottom " + pctSpacing + "%!");
this.add(tab, "w " + pctTabW + "%!, h " + pctTabH + "%!,"
+ " gap 0 0 " + pctSpacing + " " + pctSpacing + "%!");
this.allVTabs.add(tab);
// Add card to content panel
this.pnlContent.add(childPanels.get(i), "CARD" + i);
}
final JPanel bottomSpacer = new JPanel();
bottomSpacer.setOpaque(false);
this.add(bottomSpacer, "w 10%!, h " + (pctInsetH + pctSpacing) + "%!");
}
/**