Dieser Beitrag "DeNA IP Platform Division Adventskalender 2017" Dies ist der Artikel am 19. Tag.
In meinem Team codieren alle serverseitigen Ingenieure mit IntelliJ IDEA. Kürzlich habe ich mich plötzlich gefragt: "Wie erstelle ich ein IntelliJ IDEA-Plug-In?". Während des Studiums habe ich versucht, so etwas wie ein Desktop-Maskottchen zu erstellen, das auf der IDE angezeigt wird. Daher möchte ich den Ablauf zusammenfassen.
Wenn Sie die IDE starten, erscheinen seltsame Kreaturen. Während Sie codieren, werden Erfahrungswerte (Exp) akkumuliert. (Ich wollte eine Funktion hinzufügen, die das Codieren etwas mehr unterstützt, aber das ist okay)
IntelliJ IDEA ist erforderlich, um ein Plug-In zu erstellen. (Community Edition ist ebenfalls akzeptabel) Es scheint, dass es einfacher ist, während der Plug-Entwicklung zu debuggen, wenn der Quellcode von IntelliJ IDEA Community Edition ebenfalls gelöscht wird, aber ich habe ihn diesmal nicht verwendet. Das detaillierte Verfahren ist im offiziellen Dokument beschrieben, daher werde ich es weglassen.
[Datei> Neues Projekt> IntelliJ Platform Plugin> Weiter] auf IntelliJ IDEA Geben Sie dem Projektnamen einen geeigneten Namen. (Diesmal ist Nunyu)
Die Basis des Plug-Ins sind die folgenden drei Arten von Komponenten.
Dieses Mal möchte ich, dass das Maskottchen beim Start der IDE projektübergreifend angezeigt wird, daher erstelle ich es mit der Komponente auf Anwendungsebene. Sie können eine neue erstellen, indem Sie mit der rechten Maustaste auf das Projektfenster klicken und [Neu> Plugin DevKit> Anwendungskomponente] auswählen. Der Komponentenname lautet "Nunyu".
Tatsächlich läuft das Plug-In jetzt auf der IDE!
Komponente initialisieren Lassen Sie uns abmelden und mit initComponent
ausführen.
src/Nunyu.java
import com.intellij.openapi.diagnostic.Logger;
...
@Override
public void initComponent() {
Logger.getInstance(Nunyu.class).info("Nunyu");
}
...
Um es auszuführen, wählen Sie [Ausführen> Debuggen] aus dem Menü. Dann wird eine weitere IntelliJ IDEA gestartet und das Plug-In ausgeführt. Und Sie können sehen, dass in der Debug-Konsole eine Meldung angezeigt wird.
Lassen Sie die Komponente "JWindow" erben, um das Fenster bei der Initialisierung anzuzeigen und das Bild zu rendern. Hier geht es um "Swing".
src/Nunyu.java
import com.intellij.openapi.components.ApplicationComponent;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class Nunyu extends JWindow implements ApplicationComponent {
private Image image;
private ImagePanel imagePanel;
public Nunyu() {
}
@Override
public void initComponent() {
initWindow();
makeDraggable();
}
public void initWindow() {
image = Toolkit.getDefaultToolkit().getImage(getClass().getResource("/images/nunyu-alpha.png "));
setSize(100, 100);
setAlwaysOnTop(true);
setBackground(new Color(1, 0, 0, 0));
imagePanel = new ImagePanel();
add(imagePanel);
setVisible(true);
}
public void makeDraggable() {
final Point startPos = new Point();
addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
startPos.setLocation(e.getPoint());
}
});
addMouseMotionListener(new MouseMotionAdapter() {
@Override
public void mouseDragged(MouseEvent e) {
setLocation(e.getXOnScreen() - startPos.x, e.getYOnScreen() - startPos.y);
}
});
}
public class ImagePanel extends JPanel {
public ImagePanel() {
setOpaque(false);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(image, 0, 0, this);
}
}
@Override
public void disposeComponent() {
// TODO: insert component disposal logic here
}
@Override
@NotNull
public String getComponentName() {
return "Nunyu";
}
}
setBackground (neue Farbe (0, 0, 0, 0))
, um das Fenster transparent zu machen.resources / images / nunyu-alpha.png
vor, setzen Sie es auf setOpaque (false)
und rendern Sie es.setAlwaysOnTop (true)
makeDraggable ()
Wenn Sie es jetzt ausführen, sehen Sie die Maskottchen, die Sie ziehen können!
Selbst wenn die IDE den Fokus verliert, bleibt das Maskottchen bei dieser Geschwindigkeit oben angezeigt und verschwindet nicht. Es ist nervig. Wenn die IDE den Fokus verliert, füge ich einen Prozess hinzu, um das Maskottchen gleichzeitig zu löschen.
src/Nunyu.java
@Override
public void initComponent() {
initWindow();
setupFocusEvent();
}
...
public void setupFocusEvent() {
WindowManager.getInstance().addListener(new WindowManagerListener() {
@Override
public void frameCreated(IdeFrame frame) {
WindowManager.getInstance().getFrame(frame.getProject()).addWindowFocusListener(new WindowFocusListener() {
@Override
public void windowGainedFocus(WindowEvent e) {
setVisible(true);
}
@Override
public void windowLostFocus(WindowEvent e) {
if (e.getOppositeWindow() == null) {
setVisible(false);
}
}
});
}
@Override
public void beforeFrameReleased(IdeFrame frame) {
}
});
}
Fügen Sie einen "WindowManagerListener" -Listener hinzu und fügen Sie diesem Fenster jedes Mal einen "WindowFocusListener" hinzu, wenn ein Frame in der IDE erstellt wird. Implementieren Sie in diesem Listener "windowGainedFocus", das ausgelöst wird, wenn das Fenster den Fokus erhält, und "windowLostFocus", das ausgelöst wird, wenn das Fenster den Fokus verliert. Ich möchte das Maskottchen anzeigen, wenn das Fenster auf der IDE den Fokus erhält, damit ich "setVisible (true)" aufrufen kann. Wenn Sie dagegen den Fokus verlieren, können Sie "e.getOppositeWindow ()" verwenden, um das Fenster abzurufen, das der nächste Fokus sein wird. Wenn dies jedoch "null" ist, hat die IDE keinen Fokus, also "setVisible" Call (false) `.
Wenn ich das nächste Mal im Editor codiere, werde ich versuchen, dem Maskottchen einen Erfahrungswert zu geben. Dies erfordert das Verknüpfen von Editor-Tastenanschlägen. Erweitern Sie jedoch "editorTypedHandler", um dies zu erreichen.
src/MyTypedHandler.java
import com.intellij.codeInsight.editorActions.AutoFormatTypedHandler;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.actionSystem.TypedActionHandler;
import org.jetbrains.annotations.NotNull;
public class MyTypedHandler extends AutoFormatTypedHandler {
public MyTypedHandler(TypedActionHandler originalHandler) {
super(originalHandler);
}
@Override
public void execute(@NotNull Editor editor, char charTyped, @NotNull DataContext dataContext) {
super.execute(editor, charTyped, dataContext);
Logger.getInstance(Nunyu.class).info("Typed: " + charTyped);
}
}
resources/META-INF/plugin.xml
...
<extensions defaultExtensionNs="com.intellij">
<editorTypedHandler implementationClass="MyTypedHandler"/>
</extensions>
...
Wenn ein Zeichen in den Editor eingegeben wird, wird "execute ()" aufgerufen. Versuchen Sie, die gedrückte Taste im Protokoll auszugeben, während Sie "super.execute ()" aufrufen, um das Standardverhalten nicht zu ändern. Versuchen Sie es jetzt auszuführen und bearbeiten Sie etwas in der IDE, die gestartet wird. Sie können sehen, dass der eingegebene Schlüssel im Infoprotokoll angezeigt wird. So haken Sie diesen Schlüssel ein, aber es scheint Es gibt auch eine Möglichkeit, TypedHandlerDelegate zu verwenden, aber als ich es versuchte, war es in der IDE Als das AutoCompletion-Popup herauskam, schien das Ereignis nicht zu kommen, also funktionierte es nicht. (Ehrlich gesagt, ich weiß nicht, was die richtige Antwort ist.)
Selbst wenn ich das Maskottchen erleben kann, ist es traurig, dass es zurückgesetzt wird, wenn die IDE neu gestartet wird. Machen wir es also möglich, den als nächstes angegebenen Erfahrungswert dauerhaft zu machen. Verwenden Sie "PersistentStateComponent", um Daten im Plug-In beizubehalten.
src/MyService.java
import com.intellij.openapi.components.PersistentStateComponent;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.components.State;
import com.intellij.openapi.components.Storage;
@State(
name = "MyService",
storages = {
@Storage("nunyu.xml"),
}
)
class MyService implements PersistentStateComponent<MyService.State> {
static class State {
public Integer exp = 0;
}
State myState;
public MyService() {
this.myState = new State();
}
public State getState() {
return myState;
}
public void loadState(State state) {
myState = state;
}
public static MyService getInstance() {
return ServiceManager.getService(MyService.class);
}
}
Ich habe eine Box implementiert, die einfach die Ganzzahl "exp" hat. Sie können das Ziel so festlegen, dass es mit der Annotation "@ State" beibehalten wird.
Vergessen Sie auch nicht, in plugin.xml
zu erwähnen, um diesen Service zu nutzen.
resources/META-INF/plugin.xml
...
<extensions defaultExtensionNs="com.intellij">
<applicationService serviceInterface="MyService" serviceImplementation="MyService"/>
</extensions>
...
Registrieren Sie sich als applicationService
, da dieser von Komponenten auf Anwendungsebene verwendet wird. Beachten Sie, dass es andere projectService
usw. gibt.
Beginnen wir zunächst mit der Anzeige des Erfahrungswerts auf dem Bildschirm.
Schreiben Sie die paintComponent ()
-Methode der ImagePanel
-Klasse neu, um die exp
des MyService
anzuzeigen.
Bereiten Sie außerdem die Methode repaint ()
vor, damit Sie jedes Mal neu zeichnen können, wenn sich der Erfahrungswert erhöht.
src/Nunyu.java
...
public void repaint() {
imagePanel.repaint();
}
...
public class ImagePanel extends JPanel {
...
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(image, 0, 0, this);
g.drawString("Exp. " + MyService.getInstance().myState.exp, 0, 10);
}
}
...
Schreiben Sie als Nächstes einen Prozess, um den Erfahrungswert zum Zeitpunkt der Tasteneingabe zu erhöhen und neu zu zeichnen.
src/MyService.java
...
public void increment() {
myState.exp++;
}
...
src/MyTypedHandler.java
...
@Override
public void execute(@NotNull Editor editor, char charTyped, @NotNull DataContext dataContext) {
super.execute(editor, charTyped, dataContext);
ServiceManager.getService(MyService.class).increment();
ApplicationManager.getApplication().getComponent(Nunyu.class).repaint();
}
...
Das ist es. Während Sie programmieren, wird Ihre Erfahrung stetig zunehmen!
Übrigens habe ich ein Plug-In erstellt, das keinen Nutzen hatte (lacht), aber durch Ausprobieren habe ich irgendwie verstanden, wie man ein Plug-In erstellt. Es war ziemlich schwierig, Informationen aus den Dokumenten zu finden, und ich konnte nichts wie "Was soll ich tun, wenn ich so etwas tun möchte ?!" Finden, und selbst ein so einfaches war sehr schwierig. Es gibt viele Plugins auf dem Markt, sodass Sie nach nützlichem Code oder In der Community suchen suchen können. community & topic = 20036979 & utf8 =% E2% 9C% 93) Möglicherweise finden Sie die gesuchten Informationen oder nicht! Dieser Artikel war das Ende eines Kampfes, aber wenn Sie Vorschläge haben, kommentieren Sie bitte.
Recommended Posts