X-Git-Url: https://git.nikiroo.be/?a=blobdiff_plain;f=src%2Fcom%2Fgooglecode%2Flanterna%2Fgui2%2FAbstractComponent.java;fp=src%2Fcom%2Fgooglecode%2Flanterna%2Fgui2%2FAbstractComponent.java;h=0000000000000000000000000000000000000000;hb=f06c81000632cfb5f525ca458f719338f55f9f66;hp=fb7c1e71ebe773fdab592448683fc3a972f33be9;hpb=a73a906356c971b080c36368e71a15d87e8b8d31;p=jvcard.git diff --git a/src/com/googlecode/lanterna/gui2/AbstractComponent.java b/src/com/googlecode/lanterna/gui2/AbstractComponent.java deleted file mode 100644 index fb7c1e7..0000000 --- a/src/com/googlecode/lanterna/gui2/AbstractComponent.java +++ /dev/null @@ -1,341 +0,0 @@ -/* - * This file is part of lanterna (http://code.google.com/p/lanterna/). - * - * lanterna is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - * - * Copyright (C) 2010-2015 Martin - */ -package com.googlecode.lanterna.gui2; - -import com.googlecode.lanterna.TerminalPosition; -import com.googlecode.lanterna.TerminalSize; - -/** - * AbstractComponent provides some good default behaviour for a {@code Component}, all components in Lanterna extends - * from this class in some way. If you want to write your own component that isn't interactable or theme:able, you - * probably want to extend from this class. - *

- * The way you want to declare your new {@code Component} is to pass in itself as the generic parameter, like this: - *

- * {@code
- *     public class MyComponent extends AbstractComponent {
- *         ...
- *     }
- * }
- * 
- * This was, the component renderer will be correctly setup type-wise and you will need to do fewer typecastings when - * you implement the drawing method your new component. - * - * @author Martin - * @param Should always be itself, this value will be used for the {@code ComponentRenderer} declaration - */ -public abstract class AbstractComponent implements Component { - private ComponentRenderer renderer; - private Container parent; - private TerminalSize size; - private TerminalSize explicitPreferredSize; //This is keeping the value set by the user (if setPreferredSize() is used) - private TerminalPosition position; - private LayoutData layoutData; - private boolean invalid; - - /** - * Default constructor - */ - public AbstractComponent() { - size = TerminalSize.ZERO; - position = TerminalPosition.TOP_LEFT_CORNER; - explicitPreferredSize = null; - layoutData = null; - invalid = true; - parent = null; - renderer = null; //Will be set on the first call to getRenderer() - } - - /** - * When you create a custom component, you need to implement this method and return a Renderer which is responsible - * for taking care of sizing the component, rendering it and choosing where to place the cursor (if Interactable). - * This value is intended to be overridden by custom themes. - * @return Renderer to use when sizing and drawing this component - */ - protected abstract ComponentRenderer createDefaultRenderer(); - - /** - * This will attempt to dynamically construct a {@code ComponentRenderer} class from a string, assumed to be passed - * in from a theme. This makes it possible to create themes that supplies their own {@code ComponentRenderers} that - * can even replace the ones built into lanterna and used for the bundled components. - * - * @param className Fully qualified name of the {@code ComponentRenderer} we want to instatiate - * @return {@code null} if {@code className} was null, otherwise the {@code ComponentRenderer} instance - * @throws RuntimeException If there were any problems instatiating the class - */ - @SuppressWarnings("unchecked") - protected ComponentRenderer getRendererFromTheme(String className) { - if(className == null) { - return null; - } - try { - return (ComponentRenderer)Class.forName(className).newInstance(); - } catch (InstantiationException e) { - throw new RuntimeException(e); - } catch (IllegalAccessException e) { - throw new RuntimeException(e); - } catch (ClassNotFoundException e) { - throw new RuntimeException(e); - } - } - - /** - * Takes a {@code Runnable} and immediately executes it if this is called on the designated GUI thread, otherwise - * schedules it for later invocation. - * @param runnable {@code Runnable} to execute on the GUI thread - */ - protected void runOnGUIThreadIfExistsOtherwiseRunDirect(Runnable runnable) { - if(getTextGUI() != null && getTextGUI().getGUIThread() != null) { - getTextGUI().getGUIThread().invokeLater(runnable); - } - else { - runnable.run(); - } - } - - /** - * Explicitly sets the {@code ComponentRenderer} to be used when drawing this component. - * @param renderer {@code ComponentRenderer} to be used when drawing this component - * @return Itself - */ - public T setRenderer(ComponentRenderer renderer) { - this.renderer = renderer; - return self(); - } - - @Override - public synchronized ComponentRenderer getRenderer() { - if(renderer == null) { - renderer = createDefaultRenderer(); - if(renderer == null) { - throw new IllegalStateException(getClass() + " returns a null default renderer"); - } - } - return renderer; - } - - @Override - public void invalidate() { - invalid = true; - } - - @Override - public synchronized T setSize(TerminalSize size) { - this.size = size; - return self(); - } - - @Override - public TerminalSize getSize() { - return size; - } - - @Override - public final TerminalSize getPreferredSize() { - if(explicitPreferredSize != null) { - return explicitPreferredSize; - } - else { - return calculatePreferredSize(); - } - } - - @Override - public final synchronized T setPreferredSize(TerminalSize explicitPreferredSize) { - this.explicitPreferredSize = explicitPreferredSize; - return self(); - } - - /** - * Invokes the component renderer's size calculation logic and returns the result. This value represents the - * preferred size and isn't necessarily what it will eventually be assigned later on. - * @return Size that the component renderer believes the component should be - */ - protected synchronized TerminalSize calculatePreferredSize() { - return getRenderer().getPreferredSize(self()); - } - - @Override - public synchronized T setPosition(TerminalPosition position) { - this.position = position; - return self(); - } - - @Override - public TerminalPosition getPosition() { - return position; - } - - @Override - public boolean isInvalid() { - return invalid; - } - - @Override - public final synchronized void draw(final TextGUIGraphics graphics) { - if(getRenderer() == null) { - ComponentRenderer renderer = getRendererFromTheme(graphics.getThemeDefinition(getClass()).getRenderer()); - if(renderer == null) { - renderer = createDefaultRenderer(); - if(renderer == null) { - throw new IllegalStateException(getClass() + " returned a null default renderer"); - } - } - setRenderer(renderer); - } - //Delegate drawing the component to the renderer - setSize(graphics.getSize()); - onBeforeDrawing(); - getRenderer().drawComponent(graphics, self()); - onAfterDrawing(graphics); - invalid = false; - } - - /** - * This method is called just before the component's renderer is invoked for the drawing operation. You can use this - * hook to do some last-minute adjustments to the component, as an alternative to coding it into the renderer - * itself. The component should have the correct size and position at this point, if you call {@code getSize()} and - * {@code getPosition()}. - */ - protected void onBeforeDrawing() { - //No operation by default - } - - /** - * This method is called immediately after the component's renderer has finished the drawing operation. You can use - * this hook to do some post-processing if you need, as an alternative to coding it into the renderer. The - * {@code TextGUIGraphics} supplied is the same that was fed into the renderer. - * @param graphics Graphics object you can use to manipulate the appearance of the component - */ - protected void onAfterDrawing(TextGUIGraphics graphics) { - //No operation by default - } - - @Override - public synchronized T setLayoutData(LayoutData data) { - if(layoutData != data) { - layoutData = data; - invalidate(); - } - return self(); - } - - @Override - public LayoutData getLayoutData() { - return layoutData; - } - - @Override - public Container getParent() { - return parent; - } - - @Override - public boolean hasParent(Container parent) { - if(this.parent == null) { - return false; - } - Container recursiveParent = this.parent; - while(recursiveParent != null) { - if(recursiveParent == parent) { - return true; - } - recursiveParent = recursiveParent.getParent(); - } - return false; - } - - @Override - public TextGUI getTextGUI() { - if(parent == null) { - return null; - } - return parent.getTextGUI(); - } - - @Override - public boolean isInside(Container container) { - Component test = this; - while(test.getParent() != null) { - if(test.getParent() == container) { - return true; - } - test = test.getParent(); - } - return false; - } - - @Override - public BasePane getBasePane() { - if(parent == null) { - return null; - } - return parent.getBasePane(); - } - - @Override - public TerminalPosition toBasePane(TerminalPosition position) { - Container parent = getParent(); - if(parent == null) { - return null; - } - return parent.toBasePane(getPosition().withRelative(position)); - } - - @Override - public TerminalPosition toGlobal(TerminalPosition position) { - Container parent = getParent(); - if(parent == null) { - return null; - } - return parent.toGlobal(getPosition().withRelative(position)); - } - - @Override - public synchronized Border withBorder(Border border) { - border.setComponent(this); - return border; - } - - @Override - public synchronized T addTo(Panel panel) { - panel.addComponent(this); - return self(); - } - - @Override - public synchronized void onAdded(Container container) { - parent = container; - } - - @Override - public synchronized void onRemoved(Container container) { - parent = null; - } - - /** - * This is a little hack to avoid doing typecasts all over the place when having to return {@code T}. Credit to - * avl42 for this one! - * @return Itself, but as type T - */ - @SuppressWarnings("unchecked") - protected T self() { - return (T)this; - } -}